/*** * * Copyright (c) 1996-2002, Valve LLC. All rights reserved. * * This product contains software technology licensed from Id * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * All Rights Reserved. * * Use, distribution, and modification of this source code and/or resulting * object code is restricted to non-commercial enhancements to products from * Valve LLC. All other use, distribution, or modification is prohibited * without written permission from Valve LLC. * ****/ #include "hud.h" #include "cl_util.h" #include "const.h" #include "entity_state.h" #include "cl_entity.h" #include "entity_types.h" #include "usercmd.h" #include "pm_defs.h" #include "pm_materials.h" #include "eventscripts.h" #include "ev_hldm.h" #include "r_efx.h" #include "event_api.h" #include "event_args.h" #include "in_defs.h" #include #include "r_studioint.h" #include "com_model.h" extern engine_studio_api_t IEngineStudio; static int g_tracerCount[32]; extern "C" char PM_FindTextureType( char *name ); void V_PunchAxis( int axis, float punch ); void VectorAngles( const float *forward, float *angles ); extern cvar_t *cl_lw; extern "C" { // HLDM void EV_FireGlock1( struct event_args_s *args ); void EV_FireGlock2( struct event_args_s *args ); void EV_FireShotGunSingle( struct event_args_s *args ); void EV_FireShotGunDouble( struct event_args_s *args ); void EV_FireMP5( struct event_args_s *args ); void EV_FireMP52( struct event_args_s *args ); void EV_FireGOLDENGUN( struct event_args_s *args ); void EV_FireJackal( struct event_args_s *args ); void EV_FireZAPPER( struct event_args_s *args ); void EV_Jihad( struct event_args_s *args ); //void EV_FirePython( struct event_args_s *args ); //void EV_FireGauss( struct event_args_s *args ); //void EV_SpinGauss( struct event_args_s *args ); void EV_Crowbar( struct event_args_s *args ); void EV_Boombox( struct event_args_s *args ); void EV_FireModman( struct event_args_s *args ); void EV_FireModman2( struct event_args_s *args ); //void EV_FireCrossbow2( struct event_args_s *args ); void EV_FireRpg( struct event_args_s *args ); //void EV_EgonFire( struct event_args_s *args ); //void EV_EgonStop( struct event_args_s *args ); void EV_SodaDrink( struct event_args_s *args ); void EV_TripmineFire( struct event_args_s *args ); void EV_SnarkFire( struct event_args_s *args ); void EV_FireDosh( struct event_args_s *args ); void EV_BeamKatana( struct event_args_s *args ); void EV_FOTN( struct event_args_s *args ); void EV_FireAK47( struct event_args_s *args ); void EV_FireBow( struct event_args_s *args ); void EV_FireScientist( struct event_args_s *args ); void EV_FireNStar( struct event_args_s *args ); void EV_FireMW2( struct event_args_s *args ); void EV_TrainPitchAdjust( struct event_args_s *args ); } #define VECTOR_CONE_1DEGREES Vector( 0.00873f, 0.00873f, 0.00873f ) #define VECTOR_CONE_2DEGREES Vector( 0.01745f, 0.01745f, 0.01745f ) #define VECTOR_CONE_3DEGREES Vector( 0.02618f, 0.02618f, 0.02618f ) #define VECTOR_CONE_4DEGREES Vector( 0.03490f, 0.03490f, 0.03490f ) #define VECTOR_CONE_5DEGREES Vector( 0.04362f, 0.04362f, 0.04362f ) #define VECTOR_CONE_6DEGREES Vector( 0.05234f, 0.05234f, 0.05234f ) #define VECTOR_CONE_7DEGREES Vector( 0.06105f, 0.06105f, 0.06105f ) #define VECTOR_CONE_8DEGREES Vector( 0.06976f, 0.06976f, 0.06976f ) #define VECTOR_CONE_9DEGREES Vector( 0.07846f, 0.07846f, 0.07846f ) #define VECTOR_CONE_10DEGREES Vector( 0.08716f, 0.08716f, 0.08716f ) #define VECTOR_CONE_15DEGREES Vector( 0.13053f, 0.13053f, 0.13053f ) #define VECTOR_CONE_20DEGREES Vector( 0.17365f, 0.17365f, 0.17365f ) // play a strike sound based on the texture that was hit by the attack traceline. VecSrc/VecEnd are the // original traceline endpoints used by the attacker, iBulletType is the type of bullet that hit the texture. // returns volume of strike instrument (crowbar) to play float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *vecEnd, int iBulletType ) { // hit the world, try to play sound based on texture material type char chTextureType = CHAR_TEX_CONCRETE; float fvol; float fvolbar; const char *rgsz[4]; int cnt; float fattn = ATTN_NORM; int entity; char *pTextureName; char texname[64]; char szbuffer[64]; entity = gEngfuncs.pEventAPI->EV_IndexFromTrace( ptr ); // FIXME check if playtexture sounds movevar is set // chTextureType = 0; // Player if( entity >= 1 && entity <= gEngfuncs.GetMaxClients() ) { // hit body chTextureType = CHAR_TEX_FLESH; } else if( entity == 0 ) { // get texture from entity or world (world is ent(0)) pTextureName = (char *)gEngfuncs.pEventAPI->EV_TraceTexture( ptr->ent, vecSrc, vecEnd ); if ( pTextureName ) { strcpy( texname, pTextureName ); pTextureName = texname; // strip leading '-0' or '+0~' or '{' or '!' if( *pTextureName == '-' || *pTextureName == '+' ) { pTextureName += 2; } if( *pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ' ) { pTextureName++; } // '}}' strcpy( szbuffer, pTextureName ); szbuffer[CBTEXTURENAMEMAX - 1] = 0; // get texture type chTextureType = PM_FindTextureType( szbuffer ); } } switch (chTextureType) { default: case CHAR_TEX_CONCRETE: fvol = 0.9; fvolbar = 0.6; rgsz[0] = "player/pl_step1.wav"; rgsz[1] = "player/pl_step2.wav"; cnt = 2; break; case CHAR_TEX_METAL: fvol = 0.9; fvolbar = 0.3; rgsz[0] = "player/pl_metal1.wav"; rgsz[1] = "player/pl_metal2.wav"; cnt = 2; break; case CHAR_TEX_DIRT: fvol = 0.9; fvolbar = 0.1; rgsz[0] = "player/pl_dirt1.wav"; rgsz[1] = "player/pl_dirt2.wav"; rgsz[2] = "player/pl_dirt3.wav"; cnt = 3; break; case CHAR_TEX_VENT: fvol = 0.5; fvolbar = 0.3; rgsz[0] = "player/pl_duct1.wav"; rgsz[1] = "player/pl_duct1.wav"; cnt = 2; break; case CHAR_TEX_GRATE: fvol = 0.9; fvolbar = 0.5; rgsz[0] = "player/pl_grate1.wav"; rgsz[1] = "player/pl_grate4.wav"; cnt = 2; break; case CHAR_TEX_TILE: fvol = 0.8; fvolbar = 0.2; rgsz[0] = "player/pl_tile1.wav"; rgsz[1] = "player/pl_tile3.wav"; rgsz[2] = "player/pl_tile2.wav"; rgsz[3] = "player/pl_tile4.wav"; cnt = 4; break; case CHAR_TEX_SLOSH: fvol = 0.9; fvolbar = 0.0; rgsz[0] = "player/pl_slosh1.wav"; rgsz[1] = "player/pl_slosh3.wav"; rgsz[2] = "player/pl_slosh2.wav"; rgsz[3] = "player/pl_slosh4.wav"; cnt = 4; break; case CHAR_TEX_WOOD: fvol = 0.9; fvolbar = 0.2; rgsz[0] = "debris/wood1.wav"; rgsz[1] = "debris/wood2.wav"; rgsz[2] = "debris/wood3.wav"; cnt = 3; break; case CHAR_TEX_GLASS: case CHAR_TEX_COMPUTER: fvol = 0.8; fvolbar = 0.2; rgsz[0] = "debris/glass1.wav"; rgsz[1] = "debris/glass2.wav"; rgsz[2] = "debris/glass3.wav"; cnt = 3; break; case CHAR_TEX_FLESH: if( iBulletType == BULLET_PLAYER_CROWBAR ) return 0.0; // crowbar already makes this sound fvol = 1.0; fvolbar = 0.2; rgsz[0] = "weapons/bullet_hit1.wav"; rgsz[1] = "weapons/bullet_hit2.wav"; fattn = 1.0; cnt = 2; break; } // play material hit sound gEngfuncs.pEventAPI->EV_PlaySound( 0, ptr->endpos, CHAN_STATIC, rgsz[gEngfuncs.pfnRandomLong( 0, cnt - 1 )], fvol, fattn, 0, 96 + gEngfuncs.pfnRandomLong( 0, 0xf ) ); return fvolbar; } char *EV_HLDM_DamageDecal( physent_t *pe ) { static char decalname[32]; int idx; if( pe->classnumber == 1 ) { idx = gEngfuncs.pfnRandomLong( 0, 2 ); sprintf( decalname, "{break%i", idx + 1 ); } else if( pe->rendermode != kRenderNormal ) { strcpy( decalname, "{bproof1" ); } else { idx = gEngfuncs.pfnRandomLong( 0, 4 ); sprintf( decalname, "{shot%i", idx + 1 ); } return decalname; } void EV_HLDM_GunshotDecalTrace( pmtrace_t *pTrace, char *decalName ) { int iRand; physent_t *pe; gEngfuncs.pEfxAPI->R_BulletImpactParticles( pTrace->endpos ); iRand = gEngfuncs.pfnRandomLong( 0, 0x7FFF ); if( iRand < ( 0x7fff / 2 ) )// not every bullet makes a sound. { switch( iRand % 5 ) { case 0: gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; case 1: gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric2.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; case 2: gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric3.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; case 3: gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric4.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; case 4: gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric5.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; } } pe = gEngfuncs.pEventAPI->EV_GetPhysent( pTrace->ent ); // Only decal brush models such as the world etc. if( decalName && decalName[0] && pe && ( pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP ) ) { if( CVAR_GET_FLOAT( "r_decals" ) ) { gEngfuncs.pEfxAPI->R_DecalShoot( gEngfuncs.pEfxAPI->Draw_DecalIndex( gEngfuncs.pEfxAPI->Draw_DecalIndexFromName( decalName ) ), gEngfuncs.pEventAPI->EV_IndexFromTrace( pTrace ), 0, pTrace->endpos, 0 ); } } } void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType ) { physent_t *pe; pe = gEngfuncs.pEventAPI->EV_GetPhysent( pTrace->ent ); if( pe && ( pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP ) ) { switch( iBulletType ) { case BULLET_PLAYER_9MM: case BULLET_MONSTER_9MM: case BULLET_PLAYER_MP5: case BULLET_MONSTER_MP5: case BULLET_PLAYER_BUCKSHOT: case BULLET_PLAYER_357: case BULLET_PLAYER_GOLDENGUN: case BULLET_PLAYER_JACKAL: case BULLET_PLAYER_ZAPPER: default: // smoke and decal EV_HLDM_GunshotDecalTrace( pTrace, EV_HLDM_DamageDecal( pe ) ); break; } } } int EV_HLDM_CheckTracer( int idx, float *vecSrc, float *end, float *forward, float *right, int iBulletType, int iTracerFreq, int *tracerCount ) { int tracer = 0; int i; qboolean player = idx >= 1 && idx <= gEngfuncs.GetMaxClients() ? true : false; if( iTracerFreq != 0 && ( (*tracerCount)++ % iTracerFreq ) == 0 ) { vec3_t vecTracerSrc; if( player ) { vec3_t offset( 0, 0, -4 ); // adjust tracer position for player for( i = 0; i < 3; i++ ) { vecTracerSrc[i] = vecSrc[i] + offset[i] + right[i] * 2 + forward[i] * 16; } } else { VectorCopy( vecSrc, vecTracerSrc ); } if( iTracerFreq != 1 ) // guns that always trace also always decal tracer = 1; switch( iBulletType ) { case BULLET_PLAYER_MP5: case BULLET_MONSTER_MP5: case BULLET_MONSTER_9MM: case BULLET_MONSTER_12MM: default: EV_CreateTracer( vecTracerSrc, end ); break; } } return tracer; } /* ================ FireBullets Go to the trouble of combining multiple pellets into a single damage call. ================ */ void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int cShots, float *vecSrc, float *vecDirShooting, float flDistance, int iBulletType, int iTracerFreq, int *tracerCount, float flSpreadX, float flSpreadY ) { int i; pmtrace_t tr; int iShot; int tracer; for( iShot = 1; iShot <= cShots; iShot++ ) { vec3_t vecDir, vecEnd; float x, y, z; //We randomize for the Shotgun. if( iBulletType == BULLET_PLAYER_BUCKSHOT ) { do{ x = gEngfuncs.pfnRandomFloat( -0.5, 0.5 ) + gEngfuncs.pfnRandomFloat( -0.5, 0.5 ); y = gEngfuncs.pfnRandomFloat( -0.5, 0.5 ) + gEngfuncs.pfnRandomFloat( -0.5, 0.5 ); z = x * x + y * y; }while( z > 1 ); for( i = 0 ; i < 3; i++ ) { vecDir[i] = vecDirShooting[i] + x * flSpreadX * right[i] + y * flSpreadY * up [i]; vecEnd[i] = vecSrc[i] + flDistance * vecDir[i]; } }//But other guns already have their spread randomized in the synched spread. else { for( i = 0 ; i < 3; i++ ) { vecDir[i] = vecDirShooting[i] + flSpreadX * right[i] + flSpreadY * up [i]; vecEnd[i] = vecSrc[i] + flDistance * vecDir[i]; } } gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); // Store off the old count gEngfuncs.pEventAPI->EV_PushPMStates(); // Now add in all of the players. gEngfuncs.pEventAPI->EV_SetSolidPlayers( idx - 1 ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr ); tracer = EV_HLDM_CheckTracer( idx, vecSrc, tr.endpos, forward, right, iBulletType, iTracerFreq, tracerCount ); // do damage, paint decals if( tr.fraction != 1.0f ) { switch( iBulletType ) { default: case BULLET_PLAYER_9MM: EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); break; case BULLET_PLAYER_MP5: if( !tracer ) { EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); } break; case BULLET_PLAYER_BUCKSHOT: EV_HLDM_DecalGunshot( &tr, iBulletType ); break; case BULLET_PLAYER_357: EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); break; case BULLET_PLAYER_GOLDENGUN: if( !tracer ) { EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); } break; case BULLET_PLAYER_JACKAL: if( !tracer ) { EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); } break; case BULLET_PLAYER_ZAPPER: if( !tracer ) { EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); } break; } } gEngfuncs.pEventAPI->EV_PopPMStates(); } } //====================== // GLOCK START //====================== // Shared Glock fire implementation for EV_FireGlock1 and EV_FireGlock2. static void EV_FireGlock_Impl( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; int empty; vec3_t ShellVelocity; vec3_t ShellOrigin; int shell; vec3_t vecSrc, vecAiming; vec3_t up, right, forward; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); empty = args->bparam1; AngleVectors( angles, forward, right, up ); shell = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/shell.mdl" );// brass shell if( EV_IsLocal( idx ) ) { EV_MuzzleFlash(); gEngfuncs.pEventAPI->EV_WeaponAnimation( empty ? GLOCK_SHOOT_EMPTY : GLOCK_SHOOT, 0 ); V_PunchAxis( 0, -2.0 ); } EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 20, -12, 4 ); EV_EjectBrass( ShellOrigin, ShellVelocity, angles[YAW], shell, TE_BOUNCE_SHELL ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/re4_fire.wav", gEngfuncs.pfnRandomFloat( 0.92, 1.0 ), ATTN_NORM, 0, 98 + gEngfuncs.pfnRandomLong( 0, 3 ) ); EV_GetGunPosition( args, vecSrc, origin ); VectorCopy( forward, vecAiming ); EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_9MM, 0, &g_tracerCount[idx - 1], args->fparam1, args->fparam2 ); } void EV_FireGlock1( event_args_t *args ) { EV_FireGlock_Impl( args ); } void EV_FireGlock2( event_args_t *args ) { EV_FireGlock_Impl( args ); } //====================== // GLOCK END //====================== //====================== // SHOTGUN START //====================== void EV_FireShotGunDouble( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; int j; vec3_t ShellVelocity; vec3_t ShellOrigin; int shell; vec3_t vecSrc, vecAiming; //vec3_t vecSpread; vec3_t up, right, forward; //float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); AngleVectors( angles, forward, right, up ); shell = gEngfuncs.pEventAPI->EV_FindModelIndex("models/shotgunshell.mdl");// brass shell if( EV_IsLocal( idx ) ) { // Add muzzle flash to current weapon model EV_MuzzleFlash(); gEngfuncs.pEventAPI->EV_WeaponAnimation( SHOTGUN_FIRE2, 0 ); V_PunchAxis( 0, -10.0 ); } for( j = 0; j < 2; j++ ) { EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 32, -12, 6 ); EV_EjectBrass( ShellOrigin, ShellVelocity, angles[ YAW ], shell, TE_BOUNCE_SHOTSHELL ); } gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/dbarrel1.wav", gEngfuncs.pfnRandomFloat( 0.98, 1.0 ), ATTN_NORM, 0, 85 + gEngfuncs.pfnRandomLong( 0, 0x1f ) ); EV_GetGunPosition( args, vecSrc, origin ); VectorCopy( forward, vecAiming ); if( gEngfuncs.GetMaxClients() > 1 ) { EV_HLDM_FireBullets( idx, forward, right, up, 8, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &g_tracerCount[idx - 1], 0.17365, 0.04362 ); } else { EV_HLDM_FireBullets( idx, forward, right, up, 12, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &g_tracerCount[idx - 1], 0.08716, 0.08716 ); } } void EV_FireShotGunSingle( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; vec3_t ShellVelocity; vec3_t ShellOrigin; int shell; vec3_t vecSrc, vecAiming; //vec3_t vecSpread; vec3_t up, right, forward; //float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); AngleVectors( angles, forward, right, up ); shell = gEngfuncs.pEventAPI->EV_FindModelIndex("models/shotgunshell.mdl");// brass shell if( EV_IsLocal( idx ) ) { // Add muzzle flash to current weapon model EV_MuzzleFlash(); gEngfuncs.pEventAPI->EV_WeaponAnimation( SHOTGUN_FIRE, 0 ); V_PunchAxis( 0, -5.0 ); } EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 32, -12, 6 ); EV_EjectBrass ( ShellOrigin, ShellVelocity, angles[YAW], shell, TE_BOUNCE_SHOTSHELL ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/sbarrel1.wav", gEngfuncs.pfnRandomFloat( 0.95, 1.0 ), ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0x1f ) ); EV_GetGunPosition( args, vecSrc, origin ); VectorCopy( forward, vecAiming ); if( gEngfuncs.GetMaxClients() > 1 ) { EV_HLDM_FireBullets( idx, forward, right, up, 4, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &g_tracerCount[idx - 1], 0.08716, 0.04362 ); } else { EV_HLDM_FireBullets( idx, forward, right, up, 6, vecSrc, vecAiming, 2048, BULLET_PLAYER_BUCKSHOT, 0, &g_tracerCount[idx - 1], 0.08716, 0.08716 ); } } //====================== // SHOTGUN END //====================== //====================== // MP5 START //====================== void EV_FireMP5( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; vec3_t ShellVelocity; vec3_t ShellOrigin; int shell; vec3_t vecSrc, vecAiming; vec3_t up, right, forward; //float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); AngleVectors( angles, forward, right, up ); shell = gEngfuncs.pEventAPI->EV_FindModelIndex("models/shell.mdl");// brass shell if( EV_IsLocal( idx ) ) { // Add muzzle flash to current weapon model EV_MuzzleFlash(); gEngfuncs.pEventAPI->EV_WeaponAnimation( MP5_FIRE1 + gEngfuncs.pfnRandomLong( 0, 2 ), 0 ); V_PunchAxis( 0, gEngfuncs.pfnRandomFloat( -2, 2 ) ); } EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 20, -12, 4 ); EV_EjectBrass ( ShellOrigin, ShellVelocity, angles[YAW], shell, TE_BOUNCE_SHELL ); switch( gEngfuncs.pfnRandomLong( 0, 1 ) ) { case 0: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/hks1.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) ); break; case 1: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/hks2.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) ); break; } EV_GetGunPosition( args, vecSrc, origin ); VectorCopy( forward, vecAiming ); EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_MP5, 2, &g_tracerCount[idx - 1], args->fparam1, args->fparam2 ); } // We only predict the animation and sound // The grenade is still launched from the server. void EV_FireMP52( event_args_t *args ) { int idx; vec3_t origin; idx = args->entindex; VectorCopy( args->origin, origin ); if( EV_IsLocal( idx ) ) { gEngfuncs.pEventAPI->EV_WeaponAnimation( MP5_LAUNCH, 0 ); V_PunchAxis( 0, -10 ); } switch( gEngfuncs.pfnRandomLong( 0, 1 ) ) { case 0: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/glauncher.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) ); break; case 1: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/glauncher2.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) ); break; } } //====================== // MP5 END //====================== void EV_FireZAPPER( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; int empty; int i; // vec3_t ShellVelocity; // vec3_t ShellOrigin; // int shell; vec3_t vecSrc, vecAiming; vec3_t vecSpread; vec3_t up, right, forward; float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); empty = args->bparam1; AngleVectors( angles, forward, right, up ); //shell = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/shell.mdl" ); if( EV_IsLocal( idx ) ) { EV_MuzzleFlash(); gEngfuncs.pEventAPI->EV_WeaponAnimation( empty ? ZAPPER_SHOOT : ZAPPER_SHOOT, 0 ); } // EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 20, -12, 4 ); // EV_EjectBrass( ShellOrigin, ShellVelocity, angles[ YAW ], shell, TE_BOUNCE_SHELL ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/zapper.wav", gEngfuncs.pfnRandomFloat( 0.92, 1.0 ), ATTN_NORM, 0, 98 + gEngfuncs.pfnRandomLong( 0, 3 ) ); EV_GetGunPosition( args, vecSrc, origin ); VectorCopy( forward, vecAiming ); for( i = 0; i < 3; i++ ) { vecSpread[i] = flSpread; } //EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, VECTOR_CONE_3DEGREES, 8192, BULLET_PLAYER_ZAPPER, 0, &tracerCount[idx-1] ); EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_ZAPPER, 0, &g_tracerCount[idx-1], args->fparam1, args->fparam2 ); if( EV_IsLocal( idx ) ) { V_PunchAxis( 0.0f, -0.5f ); } } //====================== // CROWBAR START //====================== enum crowbar_e { CROWBAR_IDLE = 0, CROWBAR_DRAW, CROWBAR_HOLSTER, CROWBAR_ATTACK1HIT, CROWBAR_ATTACK1MISS, CROWBAR_ATTACK2MISS, CROWBAR_ATTACK2HIT, CROWBAR_ATTACK3MISS, #if !CROWBAR_IDLE_ANIM CROWBAR_ATTACK3HIT #else CROWBAR_ATTACK3HIT, CROWBAR_IDLE2, CROWBAR_IDLE3 #endif }; int g_iSwing; //Only predict the miss sounds, hit sounds are still played //server side, so players don't get the wrong idea. void EV_Crowbar( event_args_t *args ) { int idx; vec3_t origin; //vec3_t angles; //vec3_t velocity; idx = args->entindex; VectorCopy( args->origin, origin ); //Play Swing sound gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/cbar_miss1.wav", 1, ATTN_NORM, 0, PITCH_NORM ); if( EV_IsLocal( idx ) ) { switch( (g_iSwing++) % 3 ) { case 0: gEngfuncs.pEventAPI->EV_WeaponAnimation( CROWBAR_ATTACK1MISS, 0 ); break; case 1: gEngfuncs.pEventAPI->EV_WeaponAnimation( CROWBAR_ATTACK2MISS, 0 ); break; case 2: gEngfuncs.pEventAPI->EV_WeaponAnimation( CROWBAR_ATTACK3MISS, 0 ); break; } } } //====================== // CROWBAR END //====================== //====================== // CROWBAR START //====================== enum fotn_e { FOTN_IDLE = 0, FOTN_IDLELONG, FOTN_LPUNCH, FOTN_RPUNCH, FOTN_DEPLOY, FOTN_HOLSTER, FOTN_BASEFIST }; int g_iSwing2; //Only predict the miss sounds, hit sounds are still played //server side, so players don't get the wrong idea. void EV_FOTN( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; idx = args->entindex; VectorCopy( args->origin, origin ); if( EV_IsLocal( idx ) ) { switch( ( g_iSwing2++ ) % 2 ) { case 0: gEngfuncs.pEventAPI->EV_WeaponAnimation( FOTN_LPUNCH, 0 ); break; case 1: gEngfuncs.pEventAPI->EV_WeaponAnimation( FOTN_RPUNCH, 0 ); break; } } } //====================== // CROWBAR END //====================== void EV_Boombox( event_args_t *args ) { // Nothing } //====================== // RPG START //====================== enum rpg_e { RPG_IDLE = 0, RPG_FIDGET, RPG_RELOAD, // to reload RPG_FIRE2, // to empty RPG_HOLSTER1, // loaded RPG_DRAW1, // loaded RPG_HOLSTER2, // unloaded RPG_DRAW_UL, // unloaded RPG_IDLE_UL, // unloaded idle RPG_FIDGET_UL // unloaded fidget }; void EV_FireRpg( event_args_t *args ) { int idx; vec3_t origin; idx = args->entindex; VectorCopy( args->origin, origin ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/bbill.wav", 0.9, ATTN_NORM, 0, PITCH_NORM ); //gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "weapons/glauncher.wav", 0.7, ATTN_NORM, 0, PITCH_NORM ); //Only play the weapon anims if I shot it. if( EV_IsLocal( idx ) ) { gEngfuncs.pEventAPI->EV_WeaponAnimation( RPG_FIRE2, 0 ); V_PunchAxis( 0, -5.0 ); } } //====================== // RPG END //====================== //====================== // SODA START //====================== enum soda_e { SODA_IDLE1 = 0, SODA_FIDGET, SODA_DRINK }; void EV_SodaDrink( event_args_t *args ) { int idx; //, iFireMode; vec3_t origin, angles; //, vecSrc, forward, right, up; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); //iFireMode = args->iparam1; //Only play the weapon anims if I shot it. if( EV_IsLocal( idx ) ) { V_PunchAxis( 0, gEngfuncs.pfnRandomLong( 0, 1 ) ); gEngfuncs.pEventAPI->EV_WeaponAnimation( SODA_DRINK, 0 ); } switch( gEngfuncs.pfnRandomLong( 0, 1 ) ) { case 0: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/soda1.wav", 1, ATTN_NORM, 0, 100 ); break; case 1: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/soda2.wav", 1, ATTN_NORM, 0, 100 ); break; } } //====================== // SODA END //====================== //====================== // TRIPMINE START //====================== enum tripmine_e { TRIPMINE_IDLE1 = 0, TRIPMINE_IDLE2, TRIPMINE_ARM1, TRIPMINE_ARM2, TRIPMINE_FIDGET, TRIPMINE_HOLSTER, TRIPMINE_DRAW, TRIPMINE_WORLD, TRIPMINE_GROUND }; //We only check if it's possible to put a trip mine //and if it is, then we play the animation. Server still places it. void EV_TripmineFire( event_args_t *args ) { int idx; vec3_t vecSrc, angles, view_ofs, forward; pmtrace_t tr; idx = args->entindex; const bool last = args->bparam1 != 0; VectorCopy( args->origin, vecSrc ); VectorCopy( args->angles, angles ); AngleVectors( angles, forward, NULL, NULL ); if( !EV_IsLocal ( idx ) ) return; // Grab predicted result for local player gEngfuncs.pEventAPI->EV_LocalPlayerViewheight( view_ofs ); vecSrc = vecSrc + view_ofs; // Store off the old count gEngfuncs.pEventAPI->EV_PushPMStates(); // Now add in all of the players. gEngfuncs.pEventAPI->EV_SetSolidPlayers( idx - 1 ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecSrc + forward * 128.0f, PM_NORMAL, -1, &tr ); //Hit something solid if( tr.fraction < 1.0f && !last ) gEngfuncs.pEventAPI->EV_WeaponAnimation( TRIPMINE_DRAW, 0 ); gEngfuncs.pEventAPI->EV_PopPMStates(); } //====================== // TRIPMINE END //====================== //====================== // SQUEAK START //====================== enum squeak_e { SQUEAK_IDLE1 = 0, SQUEAK_FIDGETFIT, SQUEAK_FIDGETNIP, SQUEAK_DOWN, SQUEAK_UP, SQUEAK_THROW }; #define VEC_HULL_MIN Vector( -16, -16, -36 ) #define VEC_DUCK_HULL_MIN Vector( -16, -16, -18 ) void EV_SnarkFire( event_args_t *args ) { int idx; vec3_t vecSrc, angles, /*view_ofs,*/ forward; pmtrace_t tr; idx = args->entindex; VectorCopy( args->origin, vecSrc ); VectorCopy( args->angles, angles ); AngleVectors( angles, forward, NULL, NULL ); if( !EV_IsLocal ( idx ) ) return; if( args->ducking ) vecSrc = vecSrc - ( VEC_HULL_MIN - VEC_DUCK_HULL_MIN ); // Store off the old count gEngfuncs.pEventAPI->EV_PushPMStates(); // Now add in all of the players. gEngfuncs.pEventAPI->EV_SetSolidPlayers( idx - 1 ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc + forward * 20, vecSrc + forward * 64, PM_NORMAL, -1, &tr ); //Find space to drop the thing. if( tr.allsolid == 0 && tr.startsolid == 0 && tr.fraction > 0.25f ) gEngfuncs.pEventAPI->EV_WeaponAnimation( SQUEAK_THROW, 0 ); gEngfuncs.pEventAPI->EV_PopPMStates(); } //====================== // SQUEAK END //====================== //====================== // DOSH START //====================== enum dosh_e { DOSH_IDLE = 0, DOSH_FIDGET, DOSH_RELOAD, // to reload DOSH_FIRE2, // to empty DOSH_HOLSTER1, // loaded DOSH_DRAW1, // loaded DOSH_HOLSTER2, // unloaded DOSH_DRAW_UL, // unloaded DOSH_IDLE_UL, // unloaded idle DOSH_FIDGET_UL // unloaded fidget }; void EV_FireDosh( event_args_t *args ) { int idx; vec3_t origin; idx = args->entindex; VectorCopy( args->origin, origin ); switch( gEngfuncs.pfnRandomLong( 0, 10 ) ) { case 0: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/dosh1.wav", 1, ATTN_NORM, 0, PITCH_NORM ); break; case 1: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/dosh2.wav", 1, ATTN_NORM, 0, PITCH_NORM ); break; case 2: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/dosh3.wav", 1, ATTN_NORM, 0, PITCH_NORM ); break; case 3: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/dosh4.wav", 1, ATTN_NORM, 0, PITCH_NORM ); break; case 4: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/dosh5.wav", 1, ATTN_NORM, 0, PITCH_NORM ); break; case 5: break; case 6: break; case 7: break; case 8: break; case 9: break; case 10: break; //case 5: // gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/dosh6.wav", 1, ATTN_NORM, 0, PITCH_NORM ); // break; } //gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/rocket2.wav", 0.9, ATTN_NORM, 0, PITCH_NORM ); //gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "weapons/glauncher.wav", 0.7, ATTN_NORM, 0, PITCH_NORM ); //Only play the weapon anims if I shot it. if( EV_IsLocal( idx ) ) { gEngfuncs.pEventAPI->EV_WeaponAnimation( DOSH_FIRE2, 0 ); V_PunchAxis( 0, -5.0 ); } } //====================== // RPG END //====================== //====================== // CROWBAR START //====================== enum beamkatana_e { BEAMKATANA_IDLE = 0, BEAMKATANA_DRAW, BEAMKATANA_HOLSTER, BEAMKATANA_ATTACK1HIT, BEAMKATANA_ATTACK1MISS, BEAMKATANA_ATTACK2MISS, BEAMKATANA_ATTACK2HIT, BEAMKATANA_ATTACK3MISS, BEAMKATANA_ATTACK3HIT }; //int g_iSwing; //Only predict the miss sounds, hit sounds are still played //server side, so players don't get the wrong idea. void EV_BeamKatana( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; idx = args->entindex; VectorCopy( args->origin, origin ); //Play Swing sound gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/beamkatana_miss1.wav", 1, ATTN_NORM, 0, PITCH_NORM ); if( EV_IsLocal( idx ) ) { switch( ( g_iSwing++ ) % 3 ) { case 0: gEngfuncs.pEventAPI->EV_WeaponAnimation( BEAMKATANA_ATTACK1MISS, 0 ); break; case 1: gEngfuncs.pEventAPI->EV_WeaponAnimation( BEAMKATANA_ATTACK2MISS, 0 ); break; case 2: gEngfuncs.pEventAPI->EV_WeaponAnimation( BEAMKATANA_ATTACK3MISS, 0 ); break; } } } //====================== // CROWBAR END //====================== //====================== // AK47 START //====================== void EV_FireAK47( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; vec3_t ShellVelocity; vec3_t ShellOrigin; int shell; vec3_t vecSrc, vecAiming; vec3_t up, right, forward; float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); AngleVectors( angles, forward, right, up ); shell = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/rshell.mdl" );// rifle brass shell if( EV_IsLocal( idx ) ) { // Add muzzle flash to current weapon model EV_MuzzleFlash(); gEngfuncs.pEventAPI->EV_WeaponAnimation( AK47_SHOOT1 + gEngfuncs.pfnRandomLong( 0, 2 ), 0 ); V_PunchAxis( 0, gEngfuncs.pfnRandomFloat( -2, 2 ) ); } EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 20, -12, 4 ); EV_EjectBrass( ShellOrigin, ShellVelocity, angles[YAW], shell, TE_BOUNCE_SHELL ); switch( gEngfuncs.pfnRandomLong( 0, 1 ) ) { case 0: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/ak47-1.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) ); break; case 1: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/ak47-2.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) ); break; } EV_GetGunPosition( args, vecSrc, origin ); VectorCopy( forward, vecAiming ); if( gEngfuncs.GetMaxClients() > 1 ) { EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_357, 2, &g_tracerCount[idx-1], args->fparam1, args->fparam2 ); } else { EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_357, 2, &g_tracerCount[idx-1], args->fparam1, args->fparam2 ); } } //====================== // AK47 END //====================== //====================== // BOW START //====================== enum bow_e { BOW_IDLE1 = 0, // full BOW_IDLE2, // empty BOW_FIDGET1, // full BOW_FIDGET2, // empty BOW_FIRE1, // full BOW_FIRE2, // reload BOW_FIRE3, // empty BOW_RELOAD, // from empty BOW_DRAW1, // full BOW_DRAW2, // empty BOW_HOLSTER1, // full BOW_HOLSTER2 // empty }; void EV_FireBow( event_args_t *args ) { int idx; vec3_t origin; idx = args->entindex; VectorCopy( args->origin, origin ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/bow_fire1.wav", 1, ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) ); //gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "weapons/bow_reload1.wav", gEngfuncs.pfnRandomFloat( 0.95, 1.0 ), ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) ); //Only play the weapon anims if I shot it. if( EV_IsLocal( idx ) ) { if( args->iparam1 ) gEngfuncs.pEventAPI->EV_WeaponAnimation( BOW_FIRE1, 0 ); else gEngfuncs.pEventAPI->EV_WeaponAnimation( BOW_FIRE3, 0 ); V_PunchAxis( 0, -2.0 ); } } //====================== // BOW END //====================== //====================== // CROSSBOW START //====================== enum crossbow_e { CROSSBOW_IDLE1 = 0, // full CROSSBOW_IDLE2, // empty CROSSBOW_FIDGET1, // full CROSSBOW_FIDGET2, // empty CROSSBOW_FIRE1, // full CROSSBOW_FIRE2, // reload CROSSBOW_FIRE3, // empty CROSSBOW_RELOAD, // from empty CROSSBOW_DRAW1, // full CROSSBOW_DRAW2, // empty CROSSBOW_HOLSTER1, // full CROSSBOW_HOLSTER2 // empty }; //===================== // EV_BoltCallback // This function is used to correct the origin and angles // of the bolt, so it looks like it's stuck on the wall. //===================== void EV_BoltCallback ( struct tempent_s *ent, float frametime, float currenttime ) { ent->entity.origin = ent->entity.baseline.vuser1; ent->entity.angles = ent->entity.baseline.vuser2; } void EV_FireModman2( event_args_t *args ) { vec3_t vecSrc, vecEnd; vec3_t up, right, forward; pmtrace_t tr; int idx; vec3_t origin; vec3_t angles; vec3_t velocity; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); AngleVectors( angles, forward, right, up ); EV_GetGunPosition( args, vecSrc, origin ); VectorMA( vecSrc, 8192, forward, vecEnd ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/mman_fire1.wav", 1, ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) ); //gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "weapons/mman_reload1.wav", gEngfuncs.pfnRandomFloat( 0.95, 1.0 ), ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) ); if( EV_IsLocal( idx ) ) { if( args->iparam1 ) gEngfuncs.pEventAPI->EV_WeaponAnimation( CROSSBOW_FIRE1, 0 ); else gEngfuncs.pEventAPI->EV_WeaponAnimation( CROSSBOW_FIRE3, 0 ); } // Store off the old count gEngfuncs.pEventAPI->EV_PushPMStates(); // Now add in all of the players. gEngfuncs.pEventAPI->EV_SetSolidPlayers( idx - 1 ); gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr ); //We hit something if( tr.fraction < 1.0f ) { physent_t *pe = gEngfuncs.pEventAPI->EV_GetPhysent( tr.ent ); //Not the world, let's assume we hit something organic ( dog, cat, uncle joe, etc ). if( pe->solid != SOLID_BSP ) { switch( gEngfuncs.pfnRandomLong( 0, 1 ) ) { case 0: gEngfuncs.pEventAPI->EV_PlaySound( idx, tr.endpos, CHAN_BODY, "weapons/xbow_hitbod1.wav", 1, ATTN_NORM, 0, PITCH_NORM ); break; case 1: gEngfuncs.pEventAPI->EV_PlaySound( idx, tr.endpos, CHAN_BODY, "weapons/xbow_hitbod2.wav", 1, ATTN_NORM, 0, PITCH_NORM ); break; } } //Stick to world but don't stick to glass, it might break and leave the bolt floating. It can still stick to other non-transparent breakables though. else if( pe->rendermode == kRenderNormal ) { gEngfuncs.pEventAPI->EV_PlaySound( 0, tr.endpos, CHAN_BODY, "weapons/mman_hit1.wav", gEngfuncs.pfnRandomFloat( 0.95, 1.0 ), ATTN_NORM, 0, PITCH_NORM ); //Not underwater, do some sparks... if( gEngfuncs.PM_PointContents( tr.endpos, NULL ) != CONTENTS_WATER ) gEngfuncs.pEfxAPI->R_SparkShower( tr.endpos ); vec3_t vBoltAngles; int iModelIndex = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/crossbow_bolt.mdl" ); VectorAngles( forward, vBoltAngles ); TEMPENTITY *bolt = gEngfuncs.pEfxAPI->R_TempModel( tr.endpos - forward * 10, Vector( 0, 0, 0 ), vBoltAngles , 5, iModelIndex, TE_BOUNCE_NULL ); if( bolt ) { bolt->flags |= ( FTENT_CLIENTCUSTOM ); //So it calls the callback function. bolt->entity.baseline.vuser1 = tr.endpos - forward * 10; // Pull out a little bit bolt->entity.baseline.vuser2 = vBoltAngles; //Look forward! bolt->callback = EV_BoltCallback; //So we can set the angles and origin back. (Stick the bolt to the wall) } } } gEngfuncs.pEventAPI->EV_PopPMStates(); } //TODO: Fully predict the flying bolt. void EV_FireModman( event_args_t *args ) { int idx; vec3_t origin; idx = args->entindex; VectorCopy( args->origin, origin ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/mman_fire1.wav", 1, ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "weapons/xbow_reload1.wav", gEngfuncs.pfnRandomFloat(0.95, 1.0), ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) ); //Only play the weapon anims if I shot it. if( EV_IsLocal( idx ) ) { if( args->iparam1 ) gEngfuncs.pEventAPI->EV_WeaponAnimation( CROSSBOW_FIRE1, 0 ); else gEngfuncs.pEventAPI->EV_WeaponAnimation( CROSSBOW_FIRE3, 0 ); V_PunchAxis( 0, -2.0 ); } } //====================== // CROSSBOW END //====================== //====================== // SCIENTIST START //====================== void EV_FireScientist( event_args_t *args ) { int idx; vec3_t origin; idx = args->entindex; VectorCopy( args->origin, origin ); //gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/bow_fire1.wav", 1, ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) ); //gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "weapons/bow_reload1.wav", gEngfuncs.pfnRandomFloat( 0.95, 1.0 ), ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) ); //Only play the weapon anims if I shot it. //Only play the weapon anims if I shot it. if( EV_IsLocal( idx ) ) { gEngfuncs.pEventAPI->EV_WeaponAnimation( 3, 0 ); V_PunchAxis( 0, -5.0 ); } } //====================== // SCIENTIST END //====================== //====================== // STAR START //====================== enum nstar_e { NSTAR_IDLE = 0, // full NSTAR_FIRE, // full NSTAR_DRAW // full }; void EV_FireNStar( event_args_t *args ) { int idx; vec3_t origin; idx = args->entindex; VectorCopy( args->origin, origin ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/nstar_fire.wav", 1, ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) ); //gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "weapons/bow_reload1.wav", gEngfuncs.pfnRandomFloat( 0.95, 1.0 ), ATTN_NORM, 0, 93 + gEngfuncs.pfnRandomLong( 0, 0xF ) ); //Only play the weapon anims if I shot it. //Bug Fix if( EV_IsLocal( idx ) ) { gEngfuncs.pEventAPI->EV_WeaponAnimation( NSTAR_FIRE, 0 ); V_PunchAxis( 0, -0.5 ); } } //====================== // BOW END //====================== //====================== // MW2 START //====================== enum mw2_e { MW2_LONGIDLE = 0, MW2_IDLE1, MW2_GRENADE, MW2_RELOAD, MW2_DRAW, MW2_SHOOT1, MW2_SHOOT2, MW2_SHOOT3, MW2_DEPLOY }; void EV_FireMW2( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; vec3_t ShellVelocity; vec3_t ShellOrigin; int shell; vec3_t vecSrc, vecAiming; vec3_t up, right, forward; float flSpread = 23; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); AngleVectors( angles, forward, right, up ); shell = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/rshell.mdl" );// rifle brass shell if( EV_IsLocal( idx ) ) { // Add muzzle flash to current weapon model EV_MuzzleFlash(); gEngfuncs.pEventAPI->EV_WeaponAnimation( MW2_SHOOT1 + gEngfuncs.pfnRandomLong( 0, 2 ), 0 ); V_PunchAxis( 0, gEngfuncs.pfnRandomFloat( -20, 20 ) ); } EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 200, -120, 40 ); EV_EjectBrass( ShellOrigin, ShellVelocity, angles[YAW], shell, TE_BOUNCE_SHELL ); switch( gEngfuncs.pfnRandomLong( 0, 1 ) ) { case 0: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/m4a1_unsil-1.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) ); break; case 1: gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/m4a1_unsil-2.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) ); break; } EV_GetGunPosition( args, vecSrc, origin ); VectorCopy( forward, vecAiming ); if( gEngfuncs.GetMaxClients() > 1 ) { EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_357, 2, &g_tracerCount[idx-1], args->fparam1, args->fparam2 ); } else { EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_357, 2, &g_tracerCount[idx-1], args->fparam1, args->fparam2 ); } } //====================== // MW2 END //====================== void EV_FireGOLDENGUN( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; int empty; int i; vec3_t ShellVelocity; vec3_t ShellOrigin; int shell; vec3_t vecSrc, vecAiming; vec3_t vecSpread; vec3_t up, right, forward; float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); empty = args->bparam1; AngleVectors( angles, forward, right, up ); shell = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/shell.mdl" ); if( EV_IsLocal( idx ) ) { EV_MuzzleFlash(); gEngfuncs.pEventAPI->EV_WeaponAnimation( GOLDENGUN_FIRE1, 0 ); } EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 20, -12, 4 ); //EV_EjectBrass( ShellOrigin, ShellVelocity, angles[ YAW ], shell, TE_BOUNCE_SHELL ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/ggun_fire.wav", gEngfuncs.pfnRandomFloat( 0.92, 1.0 ), ATTN_NORM, 0, 98 + gEngfuncs.pfnRandomLong( 0, 3 ) ); EV_GetGunPosition( args, vecSrc, origin ); VectorCopy( forward, vecAiming ); for( i = 0; i < 3; i++ ) { vecSpread[i] = flSpread; } EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_GOLDENGUN, 0, &g_tracerCount[idx-1], args->fparam1, args->fparam2 ); if( EV_IsLocal( idx ) ) { V_PunchAxis( 0, -.5 ); } } void EV_FireJackal( event_args_t *args ) { int idx; vec3_t origin; vec3_t angles; vec3_t velocity; int empty; int i; vec3_t ShellVelocity; vec3_t ShellOrigin; int shell; vec3_t vecSrc, vecAiming; vec3_t vecSpread; vec3_t up, right, forward; float flSpread = 0.01; idx = args->entindex; VectorCopy( args->origin, origin ); VectorCopy( args->angles, angles ); VectorCopy( args->velocity, velocity ); empty = args->bparam1; AngleVectors( angles, forward, right, up ); shell = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/shell.mdl" ); if( EV_IsLocal( idx ) ) { EV_MuzzleFlash(); gEngfuncs.pEventAPI->EV_WeaponAnimation( GOLDENGUN_FIRE1, 0 ); } EV_GetDefaultShellInfo( args, origin, velocity, ShellVelocity, ShellOrigin, forward, right, up, 20, -12, 4 ); //EV_EjectBrass( ShellOrigin, ShellVelocity, angles[YAW], shell, TE_BOUNCE_SHELL ); gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/jackal-1.wav", gEngfuncs.pfnRandomFloat( 0.92, 1.0 ), ATTN_NORM, 0, 98 + gEngfuncs.pfnRandomLong( 0, 3 ) ); EV_GetGunPosition( args, vecSrc, origin ); VectorCopy( forward, vecAiming ); for( i = 0; i < 3; i++ ) { vecSpread[i] = flSpread; } EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_GOLDENGUN, 0, &g_tracerCount[idx-1], args->fparam1, args->fparam2 ); if( EV_IsLocal( idx ) ) { V_PunchAxis( 0, gEngfuncs.pfnRandomFloat( -10, 10 ) ); } } void EV_Jihad( event_args_t *args ) { return; } void EV_TrainPitchAdjust( event_args_t *args ) { int idx; vec3_t origin; unsigned short us_params; int noise; float m_flVolume; int pitch; int stop; const char *pszSound; idx = args->entindex; VectorCopy( args->origin, origin ); us_params = (unsigned short)args->iparam1; stop = args->bparam1; m_flVolume = (float)( us_params & 0x003f ) / 40.0f; noise = (int)( ( ( us_params ) >> 12 ) & 0x0007 ); pitch = (int)( 10.0f * (float)( ( us_params >> 6 ) & 0x003f ) ); switch( noise ) { case 1: pszSound = "plats/ttrain1.wav"; break; case 2: pszSound = "plats/ttrain2.wav"; break; case 3: pszSound = "plats/ttrain3.wav"; break; case 4: pszSound = "plats/ttrain4.wav"; break; case 5: pszSound = "plats/ttrain6.wav"; break; case 6: pszSound = "plats/ttrain7.wav"; break; default: // no sound return; } if( stop ) { gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, pszSound ); } else { //gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_STATIC, sz, m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, pitch ); } } int EV_TFC_IsAllyTeam( int iTeam1, int iTeam2 ) { return 0; }