diff --git a/cl_dll/ammo.cpp b/cl_dll/ammo.cpp index 988bd6fa..9772c0dd 100644 --- a/cl_dll/ammo.cpp +++ b/cl_dll/ammo.cpp @@ -951,7 +951,7 @@ int DrawBar( int x, int y, int width, int height, float f ) // Always show at least one pixel if we have ammo. if( w <= 0 ) w = 1; - UnpackRGB( r, g, b, RGB_GREENISH ); + UnpackRGB( r, g, b, RGB_YELLOWISH ); FillRGBA( x, y, w, height, r, g, b, 255 ); x += w; width -= w; diff --git a/cl_dll/battery.cpp b/cl_dll/battery.cpp index 2f26057f..b38ad543 100644 --- a/cl_dll/battery.cpp +++ b/cl_dll/battery.cpp @@ -74,6 +74,12 @@ int CHudBattery::Draw( float flTime ) if( gHUD.m_iHideHUDDisplay & HIDEHUD_HEALTH ) return 1; + // + // HL: Visitors - Only draw (kevlar vest) value if non-zero. + // + if( m_iBat <= 0 ) + return 1; + int r, g, b, x, y, a; wrect_t rc; diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 9787a839..2045f29c 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -70,6 +70,9 @@ void EV_TripmineFire( struct event_args_s *args ); void EV_SnarkFire( struct event_args_s *args ); void EV_TrainPitchAdjust( struct event_args_s *args ); + +void EV_Pipe( struct event_args_s *args ); +void EV_FireSniper( struct event_args_s *args ); } #define VECTOR_CONE_1DEGREES Vector( 0.00873, 0.00873, 0.00873 ) @@ -359,6 +362,7 @@ int EV_HLDM_CheckTracer( int idx, float *vecSrc, float *end, float *forward, flo case BULLET_MONSTER_MP5: case BULLET_MONSTER_9MM: case BULLET_MONSTER_12MM: + case BULLET_PLAYER_SNIPER: default: EV_CreateTracer( vecTracerSrc, end ); break; @@ -445,6 +449,7 @@ void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int EV_HLDM_DecalGunshot( &tr, iBulletType ); break; case BULLET_PLAYER_357: + case BULLET_PLAYER_SNIPER: EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); EV_HLDM_DecalGunshot( &tr, iBulletType ); break; @@ -1743,3 +1748,126 @@ int EV_TFC_IsAllyTeam( int iTeam1, int iTeam2 ) { return 0; } + +//====================== +// PIPE START +//====================== +enum pipe_e +{ + PIPE_IDLE1 = 0, + PIPE_DRAW, + PIPE_HOLSTER, + PIPE_ATTACK1HIT, + PIPE_ATTACK1MISS, + PIPE_ATTACK2MISS, + PIPE_ATTACK2HIT, + PIPE_ATTACK3MISS, + PIPE_ATTACK3HIT, + PIPE_IDLE2, + PIPE_IDLE3, +}; + +//Only predict the miss sounds, hit sounds are still played +//server side, so players don't get the wrong idea. +void EV_Pipe( 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 ) ) + { + gEngfuncs.pEventAPI->EV_WeaponAnimation( PIPE_ATTACK1MISS, 1 ); + + switch( ( g_iSwing++ ) % 3 ) + { + case 0: + gEngfuncs.pEventAPI->EV_WeaponAnimation( PIPE_ATTACK1MISS, 1 ); + break; + case 1: + gEngfuncs.pEventAPI->EV_WeaponAnimation( PIPE_ATTACK2MISS, 1 ); + break; + case 2: + gEngfuncs.pEventAPI->EV_WeaponAnimation( PIPE_ATTACK3MISS, 1 ); + break; + } + } +} +//====================== +// PIPE END +//====================== + +//====================== +// SNIPER START +//====================== +enum sniper_e +{ + SNIPER_IDLE1 = 0, + SNIPER_SHOOT1, + SNIPER_SHOOT2, + SNIPER_RELOAD, + SNIPER_DRAW, +}; + +void EV_FireSniper( event_args_t *args ) +{ + int idx; + vec3_t origin; + vec3_t angles; + vec3_t velocity; + + 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 ); + + if( EV_IsLocal( idx ) ) + { + // Add muzzle flash to current weapon model + EV_MuzzleFlash(); + + switch( gEngfuncs.pfnRandomLong( 0, 1 ) ) + { + case 0: + gEngfuncs.pEventAPI->EV_WeaponAnimation( SNIPER_SHOOT1, 0 ); + break; + case 1: + gEngfuncs.pEventAPI->EV_WeaponAnimation( SNIPER_SHOOT2, 0 ); + break; + } + + V_PunchAxis( 0, -10.0 ); + } + + switch( gEngfuncs.pfnRandomLong( 0, 1 ) ) + { + case 0: + gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/sniper_fire1.wav", gEngfuncs.pfnRandomFloat( 0.8, 0.9 ), ATTN_NORM, 0, PITCH_NORM ); + break; + case 1: + gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/sniper_fire2.wav", gEngfuncs.pfnRandomFloat( 0.8, 0.9 ), ATTN_NORM, 0, PITCH_NORM ); + break; + } + + EV_GetGunPosition( args, vecSrc, origin ); + + VectorCopy( forward, vecAiming ); + + EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_SNIPER, 0, 0, args->fparam1, args->fparam2 ); +} +//====================== +// SNIPER END +//====================== diff --git a/cl_dll/ev_hldm.h b/cl_dll/ev_hldm.h index bff43b1e..e1e5c9bb 100644 --- a/cl_dll/ev_hldm.h +++ b/cl_dll/ev_hldm.h @@ -15,6 +15,7 @@ typedef enum BULLET_PLAYER_9MM, // glock BULLET_PLAYER_MP5, // mp5 BULLET_PLAYER_357, // python + BULLET_PLAYER_SNIPER, // sniper BULLET_PLAYER_BUCKSHOT, // shotgun BULLET_PLAYER_CROWBAR, // crowbar swipe diff --git a/cl_dll/flashlight.cpp b/cl_dll/flashlight.cpp index 8b8a8d0e..850417a6 100644 --- a/cl_dll/flashlight.cpp +++ b/cl_dll/flashlight.cpp @@ -106,7 +106,7 @@ int CHudFlashlight::Draw( float flTime ) int r, g, b, x, y, a; wrect_t rc; - if( !( gHUD.m_iWeaponBits & ( 1 << ( WEAPON_SUIT ) ) ) ) + if( !( gHUD.m_iWeaponBits & ( 1 << ( WEAPON_FLASHLIGHT ) ) ) ) return 1; if( m_fOn ) diff --git a/cl_dll/health.cpp b/cl_dll/health.cpp index d4979c35..93775b58 100644 --- a/cl_dll/health.cpp +++ b/cl_dll/health.cpp @@ -231,7 +231,7 @@ int CHudHealth::Draw( float flTime ) int iHeight = gHUD.m_iFontHeight; int iWidth = HealthWidth / 10; - FillRGBA( x, y, iWidth, iHeight, 255, 160, 0, a ); + FillRGBA( x, y, iWidth, iHeight, r, g, b, a ); } DrawDamage( flTime ); diff --git a/cl_dll/hl/hl_events.cpp b/cl_dll/hl/hl_events.cpp index c79279dd..45330d69 100644 --- a/cl_dll/hl/hl_events.cpp +++ b/cl_dll/hl/hl_events.cpp @@ -40,6 +40,9 @@ void EV_TripmineFire( struct event_args_s *args ); void EV_SnarkFire( struct event_args_s *args ); void EV_TrainPitchAdjust( struct event_args_s *args ); + +void EV_Pipe( struct event_args_s *args ); +void EV_FireSniper( struct event_args_s *args ); } /* @@ -76,4 +79,6 @@ void Game_HookEvents( void ) gEngfuncs.pfnHookEvent( "events/firehornet.sc", EV_HornetGunFire ); gEngfuncs.pfnHookEvent( "events/tripfire.sc", EV_TripmineFire ); gEngfuncs.pfnHookEvent( "events/snarkfire.sc", EV_SnarkFire ); + gEngfuncs.pfnHookEvent( "events/pipe.sc", EV_Pipe ); + gEngfuncs.pfnHookEvent( "events/sniper.sc", EV_FireSniper ); } diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index 5a17e858..06afc55c 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -67,6 +67,8 @@ CHandGrenade g_HandGren; CSatchel g_Satchel; CTripmine g_Tripmine; CSqueak g_Snark; +CPipe g_Pipe; +CSniper g_Sniper; /* ====================== @@ -637,6 +639,8 @@ void HUD_InitClientWeapons( void ) HUD_PrepEntity( &g_Satchel, &player ); HUD_PrepEntity( &g_Tripmine, &player ); HUD_PrepEntity( &g_Snark, &player ); + HUD_PrepEntity( &g_Pipe, &player ); + HUD_PrepEntity( &g_Sniper, &player ); } /* @@ -742,6 +746,12 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm case WEAPON_SNARK: pWeapon = &g_Snark; break; + case WEAPON_PIPE: + pWeapon = &g_Pipe; + break; + case WEAPON_SNIPER: + pWeapon = &g_Sniper; + break; } // Store pointer to our destination entity_state_t so we can get our origin, etc. from it diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 0f3b45bc..f26def0b 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -77,6 +77,30 @@ int __MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf ) return gHUD.MsgFunc_GameMode( pszName, iSize, pbuf ); } +int __MsgFunc_Firstperson( const char *pszName, int iSize, void *pbuf ) +{ + gHUD.MsgFunc_Firstperson( pszName, iSize, pbuf ); + return 1; +} + +int __MsgFunc_Thirdperson( const char *pszName, int iSize, void *pbuf ) +{ + gHUD.MsgFunc_Thirdperson( pszName, iSize, pbuf ); + return 1; +} + +int __MsgFunc_PlayerModel( const char *pszName, int iSize, void *pbuf ) +{ + gHUD.MsgFunc_PlayerModel( pszName, iSize, pbuf ); + return 1; +} + +int __MsgFunc_DeathCam( const char *pszName, int iSize, void *pbuf ) +{ + gHUD.MsgFunc_DeathCam( pszName, iSize, pbuf ); + return 1; +} + // TFFree Command Menu void __CmdFunc_OpenCommandMenu( void ) { @@ -160,6 +184,10 @@ void CHud::Init( void ) HOOK_MESSAGE( ViewMode ); HOOK_MESSAGE( SetFOV ); HOOK_MESSAGE( Concuss ); + HOOK_MESSAGE( Firstperson ); + HOOK_MESSAGE( Thirdperson ); + HOOK_MESSAGE( PlayerModel ); + HOOK_MESSAGE( DeathCam ); // TFFree CommandMenu HOOK_COMMAND( "+commandmenu", OpenCommandMenu ); diff --git a/cl_dll/hud.h b/cl_dll/hud.h index ec236003..097ba914 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -20,7 +20,7 @@ // CHud handles the message, calculation, and drawing the HUD // -#define RGB_YELLOWISH 0x00FFA000 //255,160,0 +#define RGB_YELLOWISH 0x00FFFFFF //255,255,255 #define RGB_REDISH 0x00FF1010 //255,160,0 #define RGB_GREENISH 0x0000A000 //0,160,0 @@ -652,6 +652,10 @@ public: void _cdecl MsgFunc_ViewMode( const char *pszName, int iSize, void *pbuf ); int _cdecl MsgFunc_SetFOV( const char *pszName, int iSize, void *pbuf ); int _cdecl MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf ); + void _cdecl MsgFunc_Firstperson( const char *pszName, int iSize, void *pbuf ); + void _cdecl MsgFunc_Thirdperson( const char *pszName, int iSize, void *pbuf ); + void _cdecl MsgFunc_PlayerModel( const char *pszName, int iSize, void *pbuf ); + void _cdecl MsgFunc_DeathCam( const char *pszName, int iSize, void *pbuf ); // Screen information SCREENINFO m_scrinfo; diff --git a/cl_dll/hud_msg.cpp b/cl_dll/hud_msg.cpp index 47f8bc92..bb74fd22 100644 --- a/cl_dll/hud_msg.cpp +++ b/cl_dll/hud_msg.cpp @@ -26,6 +26,8 @@ extern BEAM *pBeam; extern BEAM *pBeam2; +extern int cam_thirdperson; + /// USER-DEFINED SERVER MESSAGE HANDLERS int CHud::MsgFunc_ResetHUD( const char *pszName, int iSize, void *pbuf ) @@ -115,3 +117,44 @@ int CHud::MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf ) this->m_StatusIcons.DisableIcon( "dmg_concuss" ); return 1; } + +extern int cam_deathcam_enabled; +extern float cam_deathcam_yaw; + +void CHud::MsgFunc_Firstperson( const char *pszName, int iSize, void *pbuf ) +{ + cam_thirdperson = 0; +} + +void CHud::MsgFunc_Thirdperson( const char *pszName, int iSize, void *pbuf ) +{ + cam_thirdperson = 1; +} + +void CHud::MsgFunc_PlayerModel( const char *pszName, int iSize, void *pbuf ) +{ + BEGIN_READ( pbuf, iSize ); + char* model = READ_STRING(); + + gEngfuncs.Cvar_Set( "model", model ); +} + +void CHud::MsgFunc_DeathCam( const char *pszName, int iSize, void *pbuf ) +{ + int fDeathCamOn; + Vector vDeathCamPos; + + BEGIN_READ( pbuf, iSize ); + fDeathCamOn = READ_BYTE(); // Enable/Disable + + if( fDeathCamOn ) + { + cam_deathcam_enabled = 1; + cam_deathcam_yaw = 0; + } + else + { + cam_deathcam_enabled = 0; + cam_deathcam_yaw = 0; + } +} diff --git a/cl_dll/in_camera.cpp b/cl_dll/in_camera.cpp index 92051afe..b8835fde 100644 --- a/cl_dll/in_camera.cpp +++ b/cl_dll/in_camera.cpp @@ -65,6 +65,12 @@ cvar_t *c_mindistance; // pitch, yaw, dist vec3_t cam_ofs; +// +// HL: Visitors - Death camera +// +int cam_deathcam_enabled; +float cam_deathcam_yaw; + // In third person int cam_thirdperson; int cam_mousemove; //true if we are moving the cam with the mouse, False if not @@ -388,6 +394,25 @@ void DLLEXPORT CAM_Think( void ) return; } #endif + // + // HL: Visitors - Death camera. + // + if( cam_deathcam_enabled ) + { + // Store new values. + camAngles[PITCH} = 90; + camAngles[YAW] = cam_deathcam_yaw; + camAngles[ROLL] = 0; + + // slowly rotate the camera by increasing the yaw. + cam_deathcam_yaw += 0.1f; + + // Clamp camera yaw value. + if( cam_deathcam_yaw > 180 ) + cam_deathcam_yaw -= 360; + else if( cam_deathcam_yaw < -180 ) + cam_deathcam_yaw += 360; + } cam_ofs[0] = camAngles[0]; cam_ofs[1] = camAngles[1]; cam_ofs[2] = dist; diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index b581cc82..a0f5d708 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -336,10 +336,13 @@ void V_CalcViewRoll( struct ref_params_s *pparams ) if( pparams->health <= 0 && ( pparams->viewheight[2] != 0 ) ) { - // only roll the view if the player is dead and the viewheight[2] is nonzero - // this is so deadcam in multiplayer will work. - pparams->viewangles[ROLL] = 80; // dead view angle - return; + // + // HL: Visitors - No death view roll. + // + pparams->viewangles[ROLL] = 0; + + // Look straight to the ground. + pparams->viewangles[PITCH] = 90; } } @@ -1324,6 +1327,8 @@ int V_FindViewModelByWeaponModel( int weaponindex ) { "models/p_tripmine.mdl", "models/v_tripmine.mdl" }, { "models/p_satchel_radio.mdl", "models/v_satchel_radio.mdl" }, { "models/p_satchel.mdl", "models/v_satchel.mdl" }, + { "models/p_pipe.mdl", "models/v_pipe.mdl" }, + { "models/p_sniper.mdl", "models/v_sniper.mdl" }, { NULL, NULL } }; diff --git a/dlls/apache.cpp b/dlls/apache.cpp index b64a8bae..bebda35f 100644 --- a/dlls/apache.cpp +++ b/dlls/apache.cpp @@ -22,6 +22,12 @@ #include "nodes.h" #include "effects.h" +enum +{ + APACHE_BODY_ARMY = 0, + APACHE_BODY_BLACKOPS = 1, +}; + extern DLL_GLOBAL int g_iSkillLevel; #define SF_WAITFORTRIGGER (0x04 | 0x40) // UNDONE: Fix! @@ -40,6 +46,8 @@ class CApache : public CBaseMonster void Killed( entvars_t *pevAttacker, int iGib ); void GibMonster( void ); + virtual int IRelationship( CBaseEntity *pTarget ); + void SetObjectCollisionBox( void ) { pev->absmin = pev->origin + Vector( -300, -300, -172 ); @@ -122,7 +130,17 @@ void CApache::Spawn( void ) pev->movetype = MOVETYPE_FLY; pev->solid = SOLID_BBOX; - SET_MODEL( ENT( pev ), "models/apache.mdl" ); + switch( pev->body ) + { + default: + case APACHE_BODY_ARMY: + SET_MODEL( ENT( pev ), "models/apache.mdl" ); + break; + case APACHE_BODY_BLACKOPS: + SET_MODEL( ENT( pev ), "models/blkop_apache.mdl" ); + break; + } + UTIL_SetSize( pev, Vector( -32, -32, -64 ), Vector( 32, 32, 0 ) ); UTIL_SetOrigin( pev, pev->origin ); @@ -155,7 +173,7 @@ void CApache::Spawn( void ) void CApache::Precache( void ) { PRECACHE_MODEL( "models/apache.mdl" ); - + PRECACHE_MODEL( "models/blkop_apache.mdl" ); PRECACHE_SOUND( "apache/ap_rotor1.wav" ); PRECACHE_SOUND( "apache/ap_rotor2.wav" ); PRECACHE_SOUND( "apache/ap_rotor3.wav" ); @@ -921,6 +939,23 @@ void CApache::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir } } +//========================================================= +// IRelationship +//========================================================= +int CApache::IRelationship( CBaseEntity *pTarget ) +{ + if( pev->body == APACHE_BODY_ARMY && FClassnameIs( pTarget->pev, "monster_human_massassin" ) ) + { + return R_DL; + } + else if( pev->body == APACHE_BODY_BLACKOPS && FClassnameIs( pTarget->pev, "monster_human_grunt" ) ) + { + return R_DL; + } + + return CBaseMonster::IRelationship( pTarget ); +} + class CApacheHVR : public CGrenade { void Spawn( void ); diff --git a/dlls/cdll_dll.h b/dlls/cdll_dll.h index c960a6ac..aa9389fb 100644 --- a/dlls/cdll_dll.h +++ b/dlls/cdll_dll.h @@ -40,6 +40,7 @@ #define HUD_PRINTTALK 3 #define HUD_PRINTCENTER 4 +#define WEAPON_FLASHLIGHT 30 #define WEAPON_SUIT 31 #endif diff --git a/dlls/combat.cpp b/dlls/combat.cpp index 3a59844f..26d09624 100644 --- a/dlls/combat.cpp +++ b/dlls/combat.cpp @@ -1535,6 +1535,9 @@ Vector CBaseEntity::FireBulletsPlayer( ULONG cShots, Vector vecSrc, Vector vecDi case BULLET_PLAYER_357: pEntity->TraceAttack( pevAttacker, gSkillData.plrDmg357, vecDir, &tr, DMG_BULLET ); break; + case BULLET_PLAYER_SNIPER: + pEntity->TraceAttack( pevAttacker, gSkillData.plrDmg357 * 4, vecDir, &tr, DMG_BULLET ); + break; case BULLET_NONE: // FIX pEntity->TraceAttack( pevAttacker, 50, vecDir, &tr, DMG_CLUB ); TEXTURETYPE_PlaySound( &tr, vecSrc, vecEnd, iBulletType ); diff --git a/dlls/crossbow.cpp b/dlls/crossbow.cpp index d34ad25d..197806d1 100644 --- a/dlls/crossbow.cpp +++ b/dlls/crossbow.cpp @@ -443,10 +443,6 @@ void CCrossbow::FireBolt() pBolt->pev->avelocity.z = 10; #endif - if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) - // HEV suit - indicate out of ammo condition - m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.75; m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.75; diff --git a/dlls/egon.cpp b/dlls/egon.cpp index 433704ce..298b4555 100644 --- a/dlls/egon.cpp +++ b/dlls/egon.cpp @@ -531,11 +531,6 @@ class CEgonAmmo : public CBasePlayerAmmo BOOL AddAmmo( CBaseEntity *pOther ) { - if( pOther->GiveAmmo( AMMO_URANIUMBOX_GIVE, "uranium", URANIUM_MAX_CARRY ) != -1 ) - { - EMIT_SOUND( ENT( pev ), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM ); - return TRUE; - } return FALSE; } }; diff --git a/dlls/gauss.cpp b/dlls/gauss.cpp index 14aac39b..9443c3f9 100644 --- a/dlls/gauss.cpp +++ b/dlls/gauss.cpp @@ -600,11 +600,6 @@ class CGaussAmmo : public CBasePlayerAmmo } BOOL AddAmmo( CBaseEntity *pOther ) { - if( pOther->GiveAmmo( AMMO_URANIUMBOX_GIVE, "uranium", URANIUM_MAX_CARRY ) != -1 ) - { - EMIT_SOUND( ENT( pev ), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM ); - return TRUE; - } return FALSE; } }; diff --git a/dlls/glock.cpp b/dlls/glock.cpp index 1f4517e7..111a076a 100644 --- a/dlls/glock.cpp +++ b/dlls/glock.cpp @@ -160,10 +160,6 @@ void CGlock::GlockFire( float flSpread, float flCycleTime, BOOL fUseAutoAim ) m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + flCycleTime; - if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) - // HEV suit - indicate out of ammo condition - m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 ); } diff --git a/dlls/h_battery.cpp b/dlls/h_battery.cpp index fdb7c645..5c56b5c7 100644 --- a/dlls/h_battery.cpp +++ b/dlls/h_battery.cpp @@ -115,6 +115,16 @@ void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE use Off(); } + // + // HL: Visitors - No suit recharge allowed. + // + if( m_flSoundTime <= gpGlobals->time ) + { + m_flSoundTime = gpGlobals->time + 0.62; + EMIT_SOUND( ENT( pev ), CHAN_ITEM, "items/suitchargeno1.wav", 0.85, ATTN_NORM ); + } + return; + // if the player doesn't have the suit, or there is no juice left, make the deny noise if( ( m_iJuice <= 0 ) || ( !( pActivator->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) ) { diff --git a/dlls/hassassin.cpp b/dlls/hassassin.cpp index 5aac1e53..3be5ca4d 100644 --- a/dlls/hassassin.cpp +++ b/dlls/hassassin.cpp @@ -81,6 +81,7 @@ public: void DeathSound( void ); void IdleSound( void ); CUSTOM_SCHEDULES + virtual int IRelationship( CBaseEntity *pTarget ); int Save( CSave &save ); int Restore( CRestore &restore ); @@ -989,4 +990,17 @@ Schedule_t *CHAssassin::GetScheduleOfType( int Type ) return CBaseMonster::GetScheduleOfType( Type ); } + +//========================================================= +// IRelationship +//========================================================= +int CHAssassin::IRelationship( CBaseEntity *pTarget ) +{ + if( FClassnameIs( pTarget->pev, "monster_human_massassin" ) ) + { + return R_AL; + } + + return CBaseMonster::IRelationship( pTarget ); +} #endif diff --git a/dlls/hgrunt.cpp b/dlls/hgrunt.cpp index 7b0eaa2c..855c1e79 100644 --- a/dlls/hgrunt.cpp +++ b/dlls/hgrunt.cpp @@ -40,6 +40,7 @@ #include "soundent.h" #include "effects.h" #include "customentity.h" +#include "hgrunt.h" int g_fGruntQuestion; // true if an idle grunt asked a question. Cleared when someone answers. @@ -119,73 +120,6 @@ enum //========================================================= #define bits_COND_GRUNT_NOFIRE ( bits_COND_SPECIAL1 ) -class CHGrunt : public CSquadMonster -{ -public: - void Spawn( void ); - void Precache( void ); - void SetYawSpeed( void ); - int Classify( void ); - int ISoundMask( void ); - void HandleAnimEvent( MonsterEvent_t *pEvent ); - BOOL FCanCheckAttacks( void ); - BOOL CheckMeleeAttack1( float flDot, float flDist ); - BOOL CheckRangeAttack1( float flDot, float flDist ); - BOOL CheckRangeAttack2( float flDot, float flDist ); - void CheckAmmo( void ); - void SetActivity( Activity NewActivity ); - void StartTask( Task_t *pTask ); - void RunTask( Task_t *pTask ); - void DeathSound( void ); - void PainSound( void ); - void IdleSound( void ); - Vector GetGunPosition( void ); - void Shoot( void ); - void Shotgun( void ); - void PrescheduleThink( void ); - void GibMonster( void ); - void SpeakSentence( void ); - - int Save( CSave &save ); - int Restore( CRestore &restore ); - - CBaseEntity *Kick( void ); - Schedule_t *GetSchedule( void ); - Schedule_t *GetScheduleOfType( int Type ); - void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); - int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ); - - int IRelationship( CBaseEntity *pTarget ); - - BOOL FOkToSpeak( void ); - void JustSpoke( void ); - - CUSTOM_SCHEDULES - static TYPEDESCRIPTION m_SaveData[]; - - // checking the feasibility of a grenade toss is kind of costly, so we do it every couple of seconds, - // not every server frame. - float m_flNextGrenadeCheck; - float m_flNextPainTime; - float m_flLastEnemySightTime; - - Vector m_vecTossVelocity; - - BOOL m_fThrowGrenade; - BOOL m_fStanding; - BOOL m_fFirstEncounter;// only put on the handsign show in the squad's first encounter. - int m_cClipSize; - - int m_voicePitch; - - int m_iBrassShell; - int m_iShotgunShell; - - int m_iSentence; - - static const char *pGruntSentences[]; -}; - LINK_ENTITY_TO_CLASS( monster_human_grunt, CHGrunt ) TYPEDESCRIPTION CHGrunt::m_SaveData[] = @@ -267,6 +201,11 @@ int CHGrunt::IRelationship( CBaseEntity *pTarget ) return R_NM; } + if( !FClassnameIs( pev, "monster_human_massassin" ) && FClassnameIs( pTarget->pev, "monster_human_massassin" ) ) + { + return R_DL; + } + return CSquadMonster::IRelationship( pTarget ); } diff --git a/dlls/hgrunt.h b/dlls/hgrunt.h new file mode 100644 index 00000000..3cc3d813 --- /dev/null +++ b/dlls/hgrunt.h @@ -0,0 +1,86 @@ +/*** +* +* Copyright (c) 1996-2001, 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. +* +* This source code contains proprietary and confidential information of +* Valve LLC and its suppliers. Access to this code is restricted to +* persons who have executed a written SDK license with Valve. Any access, +* use or distribution of this code by or to any unlicensed person is illegal. +* +****/ + +#ifndef HGRUNT_H +#define HGRUNT_H + +class CHGrunt : public CSquadMonster +{ +public: + virtual void Spawn(void); + virtual void Precache(void); + void SetYawSpeed(void); + int Classify(void); + int ISoundMask(void); + void HandleAnimEvent(MonsterEvent_t *pEvent); + BOOL FCanCheckAttacks(void); + BOOL CheckMeleeAttack1(float flDot, float flDist); + BOOL CheckRangeAttack1(float flDot, float flDist); + BOOL CheckRangeAttack2(float flDot, float flDist); + void CheckAmmo(void); + void SetActivity(Activity NewActivity); + void StartTask(Task_t *pTask); + void RunTask(Task_t *pTask); + void DeathSound(void); + void PainSound(void); + void IdleSound(void); + Vector GetGunPosition(void); + void Shoot(void); + void Shotgun(void); + void PrescheduleThink(void); + void GibMonster(void); + void SpeakSentence(void); + + int Save(CSave &save); + int Restore(CRestore &restore); + + CBaseEntity *Kick(void); + Schedule_t *GetSchedule(void); + Schedule_t *GetScheduleOfType(int Type); + void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); + int TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType); + + int IRelationship(CBaseEntity *pTarget); + + virtual BOOL FOkToSpeak(void); + void JustSpoke(void); + + CUSTOM_SCHEDULES; + static TYPEDESCRIPTION m_SaveData[]; + + // checking the feasibility of a grenade toss is kind of costly, so we do it every couple of seconds, + // not every server frame. + float m_flNextGrenadeCheck; + float m_flNextPainTime; + float m_flLastEnemySightTime; + + Vector m_vecTossVelocity; + + BOOL m_fThrowGrenade; + BOOL m_fStanding; + BOOL m_fFirstEncounter;// only put on the handsign show in the squad's first encounter. + int m_cClipSize; + + int m_voicePitch; + + int m_iBrassShell; + int m_iShotgunShell; + + int m_iSentence; + + static const char *pGruntSentences[]; +}; + +#endif // HGRUNT_H diff --git a/dlls/items.cpp b/dlls/items.cpp index d9cc7871..f7c30e22 100644 --- a/dlls/items.cpp +++ b/dlls/items.cpp @@ -187,11 +187,6 @@ class CItemSuit : public CItem if( pPlayer->pev->weapons & ( 1<spawnflags & SF_SUIT_SHORTLOGON ) - EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_A0" ); // short version of suit logon, - else - EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_AAx" ); // long version of suit logon - pPlayer->pev->weapons |= ( 1 << WEAPON_SUIT ); return TRUE; } @@ -214,39 +209,6 @@ class CItemBattery : public CItem } BOOL MyTouch( CBasePlayer *pPlayer ) { - if( pPlayer->pev->deadflag != DEAD_NO ) - { - return FALSE; - } - - if( ( pPlayer->pev->armorvalue < MAX_NORMAL_BATTERY ) && - ( pPlayer->pev->weapons & ( 1 << WEAPON_SUIT ) ) ) - { - int pct; - char szcharge[64]; - - pPlayer->pev->armorvalue += gSkillData.batteryCapacity; - pPlayer->pev->armorvalue = min( pPlayer->pev->armorvalue, MAX_NORMAL_BATTERY ); - - EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); - - MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); - WRITE_STRING( STRING( pev->classname ) ); - MESSAGE_END(); - - // Suit reports new power level - // For some reason this wasn't working in release build -- round it. - pct = (int)( (float)( pPlayer->pev->armorvalue * 100.0 ) * ( 1.0 / MAX_NORMAL_BATTERY ) + 0.5 ); - pct = ( pct / 5 ); - if( pct > 0 ) - pct--; - - sprintf( szcharge,"!HEV_%1dP", pct ); - - //EMIT_SOUND_SUIT( ENT( pev ), szcharge ); - pPlayer->SetSuitUpdate( szcharge, FALSE, SUIT_NEXT_IN_30SEC); - return TRUE; - } return FALSE; } }; diff --git a/dlls/mp5.cpp b/dlls/mp5.cpp index 7d05d5e1..ec2d2f84 100644 --- a/dlls/mp5.cpp +++ b/dlls/mp5.cpp @@ -173,10 +173,6 @@ void CMP5::PrimaryAttack() #endif PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usMP5, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); - if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) - // HEV suit - indicate out of ammo condition - m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.1; if( m_flNextPrimaryAttack < UTIL_WeaponTimeBase() ) @@ -230,10 +226,6 @@ void CMP5::SecondaryAttack( void ) m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1; m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5;// idle pretty soon after shooting. - - if( !m_pPlayer->m_rgAmmo[m_iSecondaryAmmoType] ) - // HEV suit - indicate out of ammo condition - m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); } void CMP5::Reload( void ) diff --git a/dlls/osprey.cpp b/dlls/osprey.cpp index 95088d2b..95071902 100644 --- a/dlls/osprey.cpp +++ b/dlls/osprey.cpp @@ -23,6 +23,12 @@ #include "effects.h" #include "customentity.h" +enum +{ + OSPREY_BODY_DEFAULT = 0, + OSPREY_BODY_MEDIC = 1 +}; + typedef struct { int isValid; @@ -147,7 +153,16 @@ void COsprey::Spawn( void ) pev->movetype = MOVETYPE_FLY; pev->solid = SOLID_BBOX; - SET_MODEL( ENT( pev ), "models/osprey.mdl" ); + switch( pev->body ) + { + default: + case OSPREY_BODY_DEFAULT: + SET_MODEL( ENT( pev ), "models/osprey.mdl" ); + break; + case OSPREY_BODY_MEDIC: + SET_MODEL( ENT( pev ), "models/medosprey.mdl" ); + break; + } UTIL_SetSize( pev, Vector( -400, -400, -100 ), Vector( 400, 400, 32 ) ); UTIL_SetOrigin( pev, pev->origin ); @@ -183,6 +198,7 @@ void COsprey::Precache( void ) UTIL_PrecacheOther( "monster_human_grunt" ); PRECACHE_MODEL( "models/osprey.mdl" ); + PRECACHE_MODEL( "models/medosprey.mdl" ); PRECACHE_MODEL( "models/HVR.mdl" ); PRECACHE_SOUND( "apache/ap_rotor4.wav" ); @@ -702,6 +718,18 @@ void COsprey::DyingThink( void ) WRITE_BYTE( BREAK_METAL ); MESSAGE_END(); + // + // HL: Visitors - Needed to trigger end game sequence. + // + if( FStrEq( STRING( gpGlobals->mapname ), "vis24" ) ) + { + // If I have a target, fire! + if( !FStringNull( m_iszTriggerTarget ) ) + { + // delay already overloaded for this entity, so can't call SUB_UseTargets() + FireTargets( STRING( m_iszTriggerTarget ), this, this, USE_TOGGLE, 0 ); + } + } UTIL_Remove( this ); } } diff --git a/dlls/player.cpp b/dlls/player.cpp index 2f097072..a62393a6 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -184,6 +184,11 @@ int gmsgTeamNames = 0; int gmsgStatusText = 0; int gmsgStatusValue = 0; +int gmsgFirstperson = 0; +int gmsgThirdperson = 0; +int gmsgPlayerModel = 0; +int gmsgDeathCam = 0; + void LinkUserMessages( void ) { // Already taken care of? @@ -228,6 +233,11 @@ void LinkUserMessages( void ) gmsgStatusText = REG_USER_MSG( "StatusText", -1 ); gmsgStatusValue = REG_USER_MSG( "StatusValue", 3 ); + + gmsgFirstperson = REG_USER_MSG( "Firstperson", 0 ); + gmsgThirdperson = REG_USER_MSG( "Thirdperson", 0 ); + gmsgPlayerModel = REG_USER_MSG( "PlayerModel", -1 ); + gmsgDeathCam = REG_USER_MSG( "DeathCam", 1 ); } LINK_ENTITY_TO_CLASS( player, CBasePlayer ) @@ -348,9 +358,6 @@ void CBasePlayer::DeathSound( void ) EMIT_SOUND( ENT( pev ), CHAN_VOICE, "player/pl_pain7.wav", 1, ATTN_NORM ); break; } - - // play one of the suit death alarms - EMIT_GROUPNAME_SUIT( ENT( pev ), "HEV_DEAD" ); } // override takehealth @@ -528,26 +535,17 @@ int CBasePlayer::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, fl if( bitsDamage & DMG_CLUB ) { - if( fmajor ) - SetSuitUpdate( "!HEV_DMG4", FALSE, SUIT_NEXT_IN_30SEC ); // minor fracture bitsDamage &= ~DMG_CLUB; ffound = TRUE; } if( bitsDamage & ( DMG_FALL | DMG_CRUSH ) ) { - if( fmajor ) - SetSuitUpdate( "!HEV_DMG5", FALSE, SUIT_NEXT_IN_30SEC ); // major fracture - else - SetSuitUpdate( "!HEV_DMG4", FALSE, SUIT_NEXT_IN_30SEC ); // minor fracture - bitsDamage &= ~( DMG_FALL | DMG_CRUSH ); ffound = TRUE; } if( bitsDamage & DMG_BULLET ) { - if( m_lastDamageAmount > 5 ) - SetSuitUpdate( "!HEV_DMG6", FALSE, SUIT_NEXT_IN_30SEC ); // blood loss detected //else // SetSuitUpdate( "!HEV_DMG0", FALSE, SUIT_NEXT_IN_30SEC ); // minor laceration @@ -557,47 +555,36 @@ int CBasePlayer::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, fl if( bitsDamage & DMG_SLASH ) { - if( fmajor ) - SetSuitUpdate( "!HEV_DMG1", FALSE, SUIT_NEXT_IN_30SEC ); // major laceration - else - SetSuitUpdate( "!HEV_DMG0", FALSE, SUIT_NEXT_IN_30SEC ); // minor laceration - bitsDamage &= ~DMG_SLASH; ffound = TRUE; } if( bitsDamage & DMG_SONIC ) { - if( fmajor ) - SetSuitUpdate( "!HEV_DMG2", FALSE, SUIT_NEXT_IN_1MIN ); // internal bleeding bitsDamage &= ~DMG_SONIC; ffound = TRUE; } if( bitsDamage & ( DMG_POISON | DMG_PARALYZE ) ) { - SetSuitUpdate( "!HEV_DMG3", FALSE, SUIT_NEXT_IN_1MIN ); // blood toxins detected bitsDamage &= ~( DMG_POISON | DMG_PARALYZE ); ffound = TRUE; } if( bitsDamage & DMG_ACID ) { - SetSuitUpdate( "!HEV_DET1", FALSE, SUIT_NEXT_IN_1MIN ); // hazardous chemicals detected bitsDamage &= ~DMG_ACID; ffound = TRUE; } if( bitsDamage & DMG_NERVEGAS ) { - SetSuitUpdate( "!HEV_DET0", FALSE, SUIT_NEXT_IN_1MIN ); // biohazard detected bitsDamage &= ~DMG_NERVEGAS; ffound = TRUE; } if( bitsDamage & DMG_RADIATION ) { - SetSuitUpdate( "!HEV_DET2", FALSE, SUIT_NEXT_IN_1MIN ); // radiation detected bitsDamage &= ~DMG_RADIATION; ffound = TRUE; } @@ -609,42 +596,20 @@ int CBasePlayer::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, fl } pev->punchangle.x = -2; - +/* if( fTookDamage && !ftrivial && fmajor && flHealthPrev >= 75 ) { - // first time we take major damage... - // turn automedic on if not on - SetSuitUpdate( "!HEV_MED1", FALSE, SUIT_NEXT_IN_30MIN ); // automedic on - - // give morphine shot if not given recently - SetSuitUpdate( "!HEV_HEAL7", FALSE, SUIT_NEXT_IN_30MIN ); // morphine shot } if( fTookDamage && !ftrivial && fcritical && flHealthPrev < 75 ) { - // already took major damage, now it's critical... - if( pev->health < 6 ) - SetSuitUpdate( "!HEV_HLTH3", FALSE, SUIT_NEXT_IN_10MIN ); // near death - else if( pev->health < 20 ) - SetSuitUpdate( "!HEV_HLTH2", FALSE, SUIT_NEXT_IN_10MIN ); // health critical - - // give critical health warnings - if( !RANDOM_LONG( 0, 3 ) && flHealthPrev < 50 ) - SetSuitUpdate( "!HEV_DMG7", FALSE, SUIT_NEXT_IN_5MIN ); //seek medical attention } // if we're taking time based damage, warn about its continuing effects if( fTookDamage && ( bitsDamageType & DMG_TIMEBASED ) && flHealthPrev < 75 ) { - if( flHealthPrev < 50 ) - { - if( !RANDOM_LONG( 0, 3 ) ) - SetSuitUpdate( "!HEV_DMG7", FALSE, SUIT_NEXT_IN_5MIN ); //seek medical attention - } - else - SetSuitUpdate( "!HEV_HLTH1", FALSE, SUIT_NEXT_IN_10MIN ); // health dropping } - +*/ return fTookDamage; } @@ -889,6 +854,19 @@ void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib ) WRITE_BYTE( 0 ); MESSAGE_END(); + // + // HL: Visitors - Go to thirdperson. + // + MESSAGE_BEGIN( MSG_ONE, gmsgThirdperson, NULL, pev ); + MESSAGE_END(); + + // + // HL: Visitors - Enable Death camera. + // + MESSAGE_BEGIN( MSG_ONE, gmsgDeathCam, NULL, pev ); + WRITE_BYTE( 1 ); // Enable/Disable + MESSAGE_END(); + // UNDONE: Put this in, but add FFADE_PERMANENT and make fade time 8.8 instead of 4.12 // UTIL_ScreenFade( edict(), Vector( 128, 0, 0 ), 6, 15, 255, FFADE_OUT | FFADE_MODULATE ); @@ -1990,7 +1968,6 @@ void CBasePlayer::CheckTimeBasedDamage() { m_rgbTimeBasedDamage[i] = 0; m_rgItems[ITEM_ANTIDOTE]--; - SetSuitUpdate( "!HEV_HEAL4", FALSE, SUIT_REPEAT_OK ); } } @@ -3190,7 +3167,7 @@ void CBasePlayer::FlashlightTurnOn( void ) return; } - if( (pev->weapons & ( 1 << WEAPON_SUIT ) ) ) + if( (pev->weapons & ( 1 << WEAPON_FLASHLIGHT ) ) ) { EMIT_SOUND_DYN( ENT( pev ), CHAN_WEAPON, SOUND_FLASHLIGHT_ON, 1.0, ATTN_NORM, 0, PITCH_NORM ); SetBits( pev->effects, EF_DIMLIGHT ); @@ -3372,6 +3349,10 @@ void CBasePlayer::CheatImpulseCommands( int iImpulse ) GiveNamedItem( "weapon_snark" ); GiveNamedItem( "weapon_hornetgun" ); #endif + GiveNamedItem( "item_flashlight" ); + GiveNamedItem( "item_bodyarmour" ); + GiveNamedItem( "weapon_pipe" ); + GiveNamedItem( "weapon_sniper" ); gEvilImpulse101 = FALSE; break; case 102: @@ -3760,6 +3741,26 @@ void CBasePlayer::UpdateClientData( void ) WRITE_BYTE( 0 ); MESSAGE_END(); + // + // HL: Visitors - Go to firstperson. + // + MESSAGE_BEGIN( MSG_ONE, gmsgFirstperson, NULL, pev ); + MESSAGE_END(); + + // + // HL: Visitors - Disable Death camera. + // + MESSAGE_BEGIN( MSG_ONE, gmsgDeathCam, NULL, pev ); + WRITE_BYTE( 0 ), + MESSAGE_END(); + + // + // HL: Visitors - Fix up player model. + // + MESSAGE_BEGIN( MSG_ONE, gmsgPlayerModel, NULL, pev ); + WRITE_STRING( "player" ); + MESSAGE_END(); + if( !m_fGameHUDInitialized ) { MESSAGE_BEGIN( MSG_ONE, gmsgInitHUD, NULL, pev ); @@ -3778,6 +3779,14 @@ void CBasePlayer::UpdateClientData( void ) InitStatusBar(); } + // + // HL: Visitors - Give suit to toggle hud on map vis07 (Security system failed) + // + if( !( pev->weapons & ( 1 << WEAPON_SUIT ) ) && FStrEq( STRING( gpGlobals->mapname ), "vis07" ) ) + { + pev->weapons |= ( 1 << WEAPON_SUIT ); + } + if( m_iHideHUD != m_iClientHideHUD ) { MESSAGE_BEGIN( MSG_ONE, gmsgHideWeapon, NULL, pev ); diff --git a/dlls/python.cpp b/dlls/python.cpp index 7bb71325..916ca1d0 100644 --- a/dlls/python.cpp +++ b/dlls/python.cpp @@ -111,6 +111,8 @@ BOOL CPython::Deploy() pev->body = 0; } + m_flSoundDelay = 0; + return DefaultDeploy( "models/v_357.mdl", "models/p_357.mdl", PYTHON_DRAW, "python", UseDecrement(), pev->body ); } @@ -126,6 +128,8 @@ void CPython::Holster( int skiplocal /* = 0 */ ) m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1.0; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 ); SendWeaponAnim( PYTHON_HOLSTER ); + + m_flSoundDelay = 0; } void CPython::SecondaryAttack( void ) @@ -202,10 +206,6 @@ void CPython::PrimaryAttack() #endif PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usFirePython, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); - if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) - // HEV suit - indicate out of ammo condition - m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); - m_flNextPrimaryAttack = 0.75; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 ); } @@ -227,9 +227,10 @@ void CPython::Reload( void ) #else bUseScope = g_pGameRules->IsMultiplayer(); #endif - if( DefaultReload( 6, PYTHON_RELOAD, 2.0, bUseScope ) ) + int iResult = DefaultReload( PYTHON_MAX_CLIP, PYTHON_RELOAD, 2.0, bUseScope ); + if( iResult ) { - m_flSoundDelay = 1.5; + m_flSoundDelay = gpGlobals->time + 1.5; } } @@ -240,7 +241,7 @@ void CPython::WeaponIdle( void ) m_pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES ); // ALERT( at_console, "%.2f\n", gpGlobals->time - m_flSoundDelay ); - if( m_flSoundDelay != 0 && m_flSoundDelay <= UTIL_WeaponTimeBase() ) + if( m_flSoundDelay != 0 && ( m_flSoundDelay <= UTIL_WeaponTimeBase() || m_flSoundDelay <= gpGlobals->time ) ) { EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_WEAPON, "weapons/357_reload1.wav", RANDOM_FLOAT( 0.8, 0.9 ), ATTN_NORM ); m_flSoundDelay = 0; diff --git a/dlls/scientist.cpp b/dlls/scientist.cpp index 4e60c58e..19627db2 100644 --- a/dlls/scientist.cpp +++ b/dlls/scientist.cpp @@ -27,14 +27,16 @@ #include "animation.h" #include "soundent.h" -#define NUM_SCIENTIST_HEADS 4 // four heads available for scientist model +#define NUM_SCIENTIST_HEADS 6 // four heads available for scientist model enum { HEAD_GLASSES = 0, HEAD_EINSTEIN = 1, HEAD_LUTHER = 2, - HEAD_SLICK = 3 + HEAD_SLICK = 3, + HEAD_NEW_BLACK = 4, + HEAD_NEW_WHITE = 5 }; enum @@ -661,7 +663,7 @@ void CScientist::Spawn( void ) } // Luther is black, make his hands black - if( pev->body == HEAD_LUTHER ) + if( pev->body == HEAD_LUTHER || pev->body == HEAD_NEW_BLACK ) pev->skin = 1; MonsterInit(); @@ -723,7 +725,7 @@ void CScientist::TalkInit() m_szGrp[TLK_MORTAL] = "SC_MORTAL"; // get voice for head - switch( pev->body % 3 ) + switch( pev->body % 6 ) { default: case HEAD_GLASSES: @@ -738,6 +740,12 @@ void CScientist::TalkInit() case HEAD_SLICK: m_voicePitch = 100; break; //slick + case HEAD_NEW_BLACK: + m_voicePitch = 90; + break; // new black + case HEAD_NEW_WHITE: + m_voicePitch = 110; + break; // new white } } @@ -1142,7 +1150,7 @@ void CDeadScientist::Spawn() } // Luther is black, make his hands black - if( pev->body == HEAD_LUTHER ) + if( pev->body == HEAD_LUTHER || pev->body == HEAD_NEW_BLACK ) pev->skin = 1; else pev->skin = 0; @@ -1233,7 +1241,7 @@ void CSittingScientist::Spawn() } // Luther is black, make his hands black - if( pev->body == HEAD_LUTHER ) + if( pev->body == HEAD_LUTHER || pev->body == HEAD_NEW_BLACK ) pev->skin = 1; m_baseSequence = LookupSequence( "sitlookleft" ); diff --git a/dlls/shotgun.cpp b/dlls/shotgun.cpp index 8c96e99c..134060d6 100644 --- a/dlls/shotgun.cpp +++ b/dlls/shotgun.cpp @@ -165,10 +165,6 @@ void CShotgun::PrimaryAttack() PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usSingleFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); - if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) - // HEV suit - indicate out of ammo condition - m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); - if( m_iClip != 0 ) m_flPumpTime = gpGlobals->time + 0.5; @@ -236,10 +232,6 @@ void CShotgun::SecondaryAttack( void ) PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usDoubleFire, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0 ); - if( !m_iClip && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 ) - // HEV suit - indicate out of ammo condition - m_pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 ); - if( m_iClip != 0 ) m_flPumpTime = gpGlobals->time + 0.95; diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index d7f9483c..b3460c0a 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -2127,6 +2127,9 @@ public: float m_acceleration; float m_deceleration; int m_state; + + BOOL m_fIsMapCredits; + float m_flMapCreditsTime; }; LINK_ENTITY_TO_CLASS( trigger_camera, CTriggerCamera ) @@ -2147,6 +2150,8 @@ TYPEDESCRIPTION CTriggerCamera::m_SaveData[] = DEFINE_FIELD( CTriggerCamera, m_acceleration, FIELD_FLOAT ), DEFINE_FIELD( CTriggerCamera, m_deceleration, FIELD_FLOAT ), DEFINE_FIELD( CTriggerCamera, m_state, FIELD_INTEGER ), + DEFINE_FIELD( CTriggerCamera, m_fIsMapCredits, FIELD_BOOLEAN ), + DEFINE_FIELD( CTriggerCamera, m_flMapCreditsTime, FIELD_TIME ), }; IMPLEMENT_SAVERESTORE( CTriggerCamera, CBaseDelay ) @@ -2163,6 +2168,8 @@ void CTriggerCamera::Spawn( void ) m_acceleration = 500; if( m_deceleration == 0 ) m_deceleration = 500; + + m_fIsMapCredits = FALSE; } void CTriggerCamera::KeyValue( KeyValueData *pkvd ) @@ -2213,6 +2220,8 @@ void CTriggerCamera::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP m_flReturnTime = gpGlobals->time + m_flWait; pev->speed = m_initialSpeed; m_targetSpeed = m_initialSpeed; + m_fIsMapCredits = FStrEq( STRING( gpGlobals->mapname ), "vis_credits" ) ? TRUE : FALSE; + m_flMapCreditsTime = gpGlobals->time + 15.0f; if( FBitSet( pev->spawnflags, SF_CAMERA_PLAYER_TARGET ) ) { @@ -2283,7 +2292,7 @@ void CTriggerCamera::FollowTarget() if( m_hPlayer == NULL ) return; - if( m_hTarget == NULL || m_flReturnTime < gpGlobals->time ) + if( m_hTarget == NULL || m_flReturnTime < gpGlobals->time || ( m_fIsMapCredits && m_flMapCreditsTime < gpGlobals->time ) ) { if( m_hPlayer->IsAlive() ) { diff --git a/dlls/visitors/flashlight.cpp b/dlls/visitors/flashlight.cpp new file mode 100644 index 00000000..df6269c2 --- /dev/null +++ b/dlls/visitors/flashlight.cpp @@ -0,0 +1,50 @@ +/*** +* +* Copyright (c) 1996-2001, 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 "extdll.h" +#include "util.h" +#include "cbase.h" +#include "weapons.h" +#include "player.h" +#include "skill.h" +#include "items.h" +#include "gamerules.h" + +class CItemFlashlight : public CItem +{ + void Spawn(void) + { + Precache(); + SET_MODEL(ENT(pev), "models/w_flashlight.mdl"); + CItem::Spawn(); + } + void Precache(void) + { + PRECACHE_MODEL("models/w_flashlight.mdl"); + PRECACHE_SOUND("items/gunpickup2.wav"); + } + BOOL MyTouch(CBasePlayer *pPlayer) + { + if (pPlayer->pev->weapons & (1 << WEAPON_FLASHLIGHT)) + return FALSE; + + EMIT_SOUND(pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM); + + pPlayer->pev->weapons |= (1 << WEAPON_FLASHLIGHT); + return TRUE; + } +}; + +LINK_ENTITY_TO_CLASS(item_flashlight, CItemFlashlight); diff --git a/dlls/visitors/kevlar.cpp b/dlls/visitors/kevlar.cpp new file mode 100644 index 00000000..cabbcb8c --- /dev/null +++ b/dlls/visitors/kevlar.cpp @@ -0,0 +1,65 @@ +/*** +* +* Copyright (c) 1996-2001, 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 "extdll.h" +#include "util.h" +#include "cbase.h" +#include "weapons.h" +#include "player.h" +#include "skill.h" +#include "items.h" +#include "gamerules.h" + +extern int gmsgItemPickup; + +class CItemKevlar : public CItem +{ + void Spawn(void) + { + Precache(); + SET_MODEL(ENT(pev), "models/w_kevlar.mdl"); + CItem::Spawn(); + } + void Precache(void) + { + PRECACHE_MODEL("models/w_kevlar.mdl"); + PRECACHE_SOUND("player/kevlar_zipper.wav"); + } + BOOL MyTouch(CBasePlayer *pPlayer) + { + if (pPlayer->pev->deadflag != DEAD_NO) + { + return FALSE; + } + + if ((pPlayer->pev->armorvalue < MAX_NORMAL_BATTERY) && + (pPlayer->pev->weapons & (1 << WEAPON_SUIT))) + { + pPlayer->pev->armorvalue += MAX_NORMAL_BATTERY; + pPlayer->pev->armorvalue = min(pPlayer->pev->armorvalue, MAX_NORMAL_BATTERY); + + EMIT_SOUND(pPlayer->edict(), CHAN_ITEM, "player/kevlar_zipper.wav", 1, ATTN_NORM); + + MESSAGE_BEGIN(MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev); + WRITE_STRING(STRING(pev->classname)); + MESSAGE_END(); + + return TRUE; + } + return FALSE; + } +}; + +LINK_ENTITY_TO_CLASS(item_bodyarmour, CItemKevlar); diff --git a/dlls/visitors/massn.cpp b/dlls/visitors/massn.cpp new file mode 100644 index 00000000..7f35aeb6 --- /dev/null +++ b/dlls/visitors/massn.cpp @@ -0,0 +1,116 @@ +/*** +* +* Copyright (c) 1996-2001, 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. +* +* This source code contains proprietary and confidential information of +* Valve LLC and its suppliers. Access to this code is restricted to +* persons who have executed a written SDK license with Valve. Any access, +* use or distribution of this code by or to any unlicensed person is illegal. +* +****/ + +#include "extdll.h" +#include "plane.h" +#include "util.h" +#include "cbase.h" +#include "monsters.h" +#include "schedule.h" +#include "animation.h" +#include "squadmonster.h" +#include "weapons.h" +#include "talkmonster.h" +#include "soundent.h" +#include "effects.h" +#include "customentity.h" +#include "hgrunt.h" + +class CMassn : public CHGrunt +{ +public: + void Spawn(void); + void Precache(void); + + BOOL FOkToSpeak(void); + + void DeathSound(void); + void PainSound(void); + void IdleSound(void); + + int IRelationship(CBaseEntity *pTarget); +}; + +LINK_ENTITY_TO_CLASS(monster_human_massassin, CMassn); + +//========================================================= +// Spawn +//========================================================= +void CMassn::Spawn() +{ + CHGrunt::Spawn(); + + SET_MODEL(ENT(pev), "models/massn.mdl"); + UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX); + + MonsterInit(); +} + +//========================================================= +// Precache - precaches all resources this monster needs +//========================================================= +void CMassn::Precache() +{ + CHGrunt::Precache(); + + PRECACHE_MODEL("models/massn.mdl"); +} + +//========================================================= +// someone else is talking - don't speak +//========================================================= +BOOL CMassn::FOkToSpeak(void) +{ + return FALSE; +} + +//========================================================= +// PainSound +//========================================================= +void CMassn::PainSound(void) +{ +} + +//========================================================= +// DeathSound +//========================================================= +void CMassn::DeathSound(void) +{ +} + +//========================================================= +// IdleSound +//========================================================= +void CMassn::IdleSound(void) +{ +} + +//========================================================= +// IRelationship - overridden because Alien Grunts are +// Human Grunt's nemesis. +//========================================================= +int CMassn::IRelationship(CBaseEntity *pTarget) +{ + if (FClassnameIs(pTarget->pev, "monster_human_grunt")) + { + return R_DL; + } + else if (FClassnameIs(pTarget->pev, "monster_hassassin")) + { + return R_AL; + } + + return CHGrunt::IRelationship(pTarget); +} \ No newline at end of file diff --git a/dlls/visitors/pipe.cpp b/dlls/visitors/pipe.cpp new file mode 100644 index 00000000..4fd42349 --- /dev/null +++ b/dlls/visitors/pipe.cpp @@ -0,0 +1,253 @@ +/*** +* +* Copyright (c) 1996-2001, 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 "extdll.h" +#include "util.h" +#include "cbase.h" +#include "monsters.h" +#include "weapons.h" +#include "nodes.h" +#include "player.h" +#include "gamerules.h" + +void FindHullIntersection(const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity); + +#define PIPE_BODYHIT_VOLUME 128 +#define PIPE_WALLHIT_VOLUME 512 + +LINK_ENTITY_TO_CLASS(weapon_pipe, CPipe); + +enum pipe_e { + PIPE_IDLE1 = 0, + PIPE_DRAW, + PIPE_HOLSTER, + PIPE_ATTACK1HIT, + PIPE_ATTACK1MISS, + PIPE_ATTACK2MISS, + PIPE_ATTACK2HIT, + PIPE_ATTACK3MISS, + PIPE_ATTACK3HIT, + PIPE_IDLE2, + PIPE_IDLE3, +}; + + +void CPipe::Spawn() +{ + Precache(); + m_iId = WEAPON_PIPE; + SET_MODEL(ENT(pev), "models/w_pipe.mdl"); + m_iClip = -1; + + FallInit();// get ready to fall down. +} + + +void CPipe::Precache(void) +{ + CCrowbar::Precache(); + + PRECACHE_MODEL("models/v_pipe.mdl"); + PRECACHE_MODEL("models/w_pipe.mdl"); + PRECACHE_MODEL("models/p_pipe.mdl"); + + m_usPipe = PRECACHE_EVENT(1, "events/pipe.sc"); +} + +int CPipe::GetItemInfo(ItemInfo *p) +{ + p->pszName = STRING(pev->classname); + p->pszAmmo1 = NULL; + p->iMaxAmmo1 = -1; + p->pszAmmo2 = NULL; + p->iMaxAmmo2 = -1; + p->iMaxClip = WEAPON_NOCLIP; + p->iSlot = 0; + p->iPosition = 1; + p->iId = WEAPON_PIPE; + p->iWeight = CROWBAR_WEIGHT; + return 1; +} + + + +BOOL CPipe::Deploy() +{ + return DefaultDeploy("models/v_pipe.mdl", "models/p_pipe.mdl", PIPE_DRAW, "pipe"); +} + +void CPipe::Holster(int skiplocal /* = 0 */) +{ + m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5; + SendWeaponAnim(PIPE_HOLSTER); +} + +void CPipe::PrimaryAttack() +{ + if (!Swing(1)) + { + SetThink(&CPipe::SwingAgain); + pev->nextthink = gpGlobals->time + 0.1f; + } +} + +int CPipe::Swing(int fFirst) +{ + int fDidHit = FALSE; + + TraceResult tr; + + UTIL_MakeVectors(m_pPlayer->pev->v_angle); + Vector vecSrc = m_pPlayer->GetGunPosition(); + Vector vecEnd = vecSrc + gpGlobals->v_forward * 32; + + UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(m_pPlayer->pev), &tr); + +#ifndef CLIENT_DLL + if (tr.flFraction >= 1.0) + { + UTIL_TraceHull(vecSrc, vecEnd, dont_ignore_monsters, head_hull, ENT(m_pPlayer->pev), &tr); + if (tr.flFraction < 1.0) + { + // Calculate the point of intersection of the line (or hull) and the object we hit + // This is and approximation of the "best" intersection + CBaseEntity *pHit = CBaseEntity::Instance(tr.pHit); + if (!pHit || pHit->IsBSPModel()) + FindHullIntersection(vecSrc, tr, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX, m_pPlayer->edict()); + vecEnd = tr.vecEndPos; // This is the point on the actual surface (the hull could have hit space) + } + } +#endif + + PLAYBACK_EVENT_FULL(FEV_NOTHOST, m_pPlayer->edict(), m_usPipe, + 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0, 0, 0, + 0.0, 0, 0.0); + + + if (tr.flFraction >= 1.0) + { + if (fFirst) + { + // miss + m_flNextPrimaryAttack = GetNextAttackDelay(0.5); + + // player "shoot" animation + m_pPlayer->SetAnimation(PLAYER_ATTACK1); + } + } + else + { + switch (((m_iSwing++) % 2) + 1) + { + case 0: + SendWeaponAnim(PIPE_ATTACK1HIT); break; + case 1: + SendWeaponAnim(PIPE_ATTACK2HIT); break; + case 2: + SendWeaponAnim(PIPE_ATTACK3HIT); break; + } + + // player "shoot" animation + m_pPlayer->SetAnimation(PLAYER_ATTACK1); + +#ifndef CLIENT_DLL + + // hit + fDidHit = TRUE; + CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit); + + ClearMultiDamage(); + + if ((m_flNextPrimaryAttack + 1 < UTIL_WeaponTimeBase()) || g_pGameRules->IsMultiplayer()) + { + // first swing does full damage + pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgCrowbar * 2, gpGlobals->v_forward, &tr, DMG_CLUB); + } + else + { + // subsequent swings do half + pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgCrowbar, gpGlobals->v_forward, &tr, DMG_CLUB); + } + ApplyMultiDamage(m_pPlayer->pev, m_pPlayer->pev); + + // play thwack, smack, or dong sound + float flVol = 1.0; + int fHitWorld = TRUE; + + if (pEntity) + { + if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE) + { + // play thwack or smack sound + switch (RANDOM_LONG(0, 2)) + { + case 0: + EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM, 0, 75); break; + case 1: + EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM, 0, 75); break; + case 2: + EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM, 0, 75); break; + } + m_pPlayer->m_iWeaponVolume = PIPE_BODYHIT_VOLUME; + if (!pEntity->IsAlive()) + return TRUE; + else + flVol = 0.1; + + fHitWorld = FALSE; + } + } + + // play texture hit sound + // UNDONE: Calculate the correct point of intersection when we hit with the hull instead of the line + + if (fHitWorld) + { + float fvolbar = TEXTURETYPE_PlaySound(&tr, vecSrc, vecSrc + (vecEnd - vecSrc) * 2, BULLET_PLAYER_CROWBAR); + + if (g_pGameRules->IsMultiplayer()) + { + // override the volume here, cause we don't play texture sounds in multiplayer, + // and fvolbar is going to be 0 from the above call. + + fvolbar = 1; + } + + // also play crowbar strike + switch (RANDOM_LONG(0, 1)) + { + case 0: + EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hit1.wav", fvolbar, ATTN_NORM, 0, 75 + RANDOM_LONG(0, 3)); // 98 + break; + case 1: + EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hit2.wav", fvolbar, ATTN_NORM, 0, 75 + RANDOM_LONG(0, 3)); // 98 + break; + } + + // delay the decal a bit + m_trHit = tr; + } + + m_pPlayer->m_iWeaponVolume = flVol * PIPE_WALLHIT_VOLUME; +#endif + m_flNextPrimaryAttack = GetNextAttackDelay(0.5f); // 0.25f + + SetThink(&CPipe::Smack); + pev->nextthink = UTIL_WeaponTimeBase() + 0.2; + + + } + return fDidHit; +} diff --git a/dlls/visitors/sniper.cpp b/dlls/visitors/sniper.cpp new file mode 100644 index 00000000..218f5bf2 --- /dev/null +++ b/dlls/visitors/sniper.cpp @@ -0,0 +1,239 @@ +/*** +* +* Copyright (c) 1996-2001, 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 "extdll.h" +#include "util.h" +#include "cbase.h" +#include "weapons.h" +#include "monsters.h" +#include "player.h" +#include "gamerules.h" + +enum sniper_e { + SNIPER_IDLE1 = 0, + SNIPER_SHOOT1, + SNIPER_SHOOT2, + SNIPER_RELOAD, + SNIPER_DRAW, +}; + +LINK_ENTITY_TO_CLASS(weapon_sniper, CSniper); + +int CSniper::GetItemInfo(ItemInfo *p) +{ + p->pszName = STRING(pev->classname); + p->pszAmmo1 = "357"; + p->iMaxAmmo1 = _357_MAX_CARRY; + p->pszAmmo2 = NULL; + p->iMaxAmmo2 = -1; + p->iMaxClip = CROSSBOW_MAX_CLIP; + p->iFlags = 0; + p->iSlot = 2; + p->iPosition = 3; + p->iId = m_iId = WEAPON_SNIPER; + p->iWeight = PYTHON_WEIGHT; + + return 1; +} + +int CSniper::AddToPlayer(CBasePlayer *pPlayer) +{ + if (CBasePlayerWeapon::AddToPlayer(pPlayer)) + { + MESSAGE_BEGIN(MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev); + WRITE_BYTE(m_iId); + MESSAGE_END(); + return TRUE; + } + return FALSE; +} + +void CSniper::Spawn() +{ + Precache(); + m_iId = WEAPON_SNIPER; + SET_MODEL(ENT(pev), "models/w_sniper.mdl"); + + m_iDefaultAmmo = CROSSBOW_DEFAULT_GIVE; + + FallInit();// get ready to fall down. +} + + +void CSniper::Precache(void) +{ + PRECACHE_MODEL("models/v_sniper.mdl"); + PRECACHE_MODEL("models/w_sniper.mdl"); + PRECACHE_MODEL("models/p_sniper.mdl"); + + PRECACHE_MODEL("models/w_sniperclip.mdl"); + PRECACHE_SOUND("items/9mmclip1.wav"); + + PRECACHE_SOUND("weapons/sniper_reload1.wav"); + PRECACHE_SOUND("weapons/scout_bolt.wav"); + PRECACHE_SOUND("weapons/scout_clipin.wav"); + PRECACHE_SOUND("weapons/scout_clipout.wav"); + + m_usFireSniper = PRECACHE_EVENT(1, "events/sniper.sc"); +} + +BOOL CSniper::Deploy() +{ + return DefaultDeploy("models/v_sniper.mdl", "models/p_sniper.mdl", SNIPER_DRAW, "sniper", UseDecrement()); +} + +void CSniper::Holster(int skiplocal /* = 0 */) +{ + m_fInReload = FALSE;// cancel any reload in progress. + + if (m_fInZoom) + { + SecondaryAttack(); + } + + m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1.0; + m_flTimeWeaponIdle = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15); +} + +void CSniper::SecondaryAttack(void) +{ + if (m_pPlayer->pev->fov != 0) + { + m_fInZoom = FALSE; + m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 0; // 0 means reset to default fov + } + else if (m_pPlayer->pev->fov != 40) + { + m_fInZoom = TRUE; + m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 40; + } + + m_flNextSecondaryAttack = 0.5; +} + +void CSniper::PrimaryAttack() +{ + // don't fire underwater + if (m_pPlayer->pev->waterlevel == 3) + { + PlayEmptySound(); + m_flNextPrimaryAttack = 0.15; + return; + } + + if (m_iClip <= 0) + { + if (!m_fFireOnEmpty) + Reload(); + else + { + EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/357_cock1.wav", 0.8, ATTN_NORM); + m_flNextPrimaryAttack = 0.15; + } + + return; + } + + m_pPlayer->m_iWeaponVolume = LOUD_GUN_VOLUME; + m_pPlayer->m_iWeaponFlash = BRIGHT_GUN_FLASH; + + m_iClip--; + + m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH; + + // player "shoot" animation + m_pPlayer->SetAnimation(PLAYER_ATTACK1); + + + UTIL_MakeVectors(m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle); + + Vector vecSrc = m_pPlayer->GetGunPosition(); + Vector vecAiming = m_pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES); + + Vector vecDir; + vecDir = m_pPlayer->FireBulletsPlayer(1, vecSrc, vecAiming, VECTOR_CONE_1DEGREES, 8192, BULLET_PLAYER_SNIPER, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed); + + int flags; +#if defined( CLIENT_WEAPONS ) + flags = FEV_NOTHOST; +#else + flags = 0; +#endif + + PLAYBACK_EVENT_FULL(flags, m_pPlayer->edict(), m_usFireSniper, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0); + + m_flNextPrimaryAttack = (46.0 / 35.0); + m_flTimeWeaponIdle = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15); +} + + +void CSniper::Reload(void) +{ + if (m_pPlayer->ammo_357 <= 0) + return; + + int iResult = DefaultReload(CROSSBOW_MAX_CLIP, SNIPER_RELOAD, 2.0); + + if (iResult) + { + if (m_pPlayer->pev->fov != 0) + { + m_fInZoom = FALSE; + m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 0; // 0 means reset to default fov + } + } +} + + +void CSniper::WeaponIdle(void) +{ + ResetEmptySound(); + + m_pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES); + + if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase()) + return; + + m_flTimeWeaponIdle = (9.0 / 16.0); + + SendWeaponAnim(SNIPER_IDLE1, UseDecrement() ? 1 : 0); +} + + +class CSniperAmmoClip : public CBasePlayerAmmo +{ + void Spawn(void) + { + Precache(); + SET_MODEL(ENT(pev), "models/w_sniperclip.mdl"); + CBasePlayerAmmo::Spawn(); + } + void Precache(void) + { + PRECACHE_MODEL("models/w_sniperclip.mdl"); + PRECACHE_SOUND("items/9mmclip1.wav"); + } + BOOL AddAmmo(CBaseEntity *pOther) + { + int bResult = (pOther->GiveAmmo(AMMO_357BOX_GIVE, "357", _357_MAX_CARRY) != -1); + if (bResult) + { + EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM); + } + return bResult; + } +}; + +LINK_ENTITY_TO_CLASS(ammo_sniper, CSniperAmmoClip); \ No newline at end of file diff --git a/dlls/weapons.cpp b/dlls/weapons.cpp index 3e2ef386..a29512ea 100644 --- a/dlls/weapons.cpp +++ b/dlls/weapons.cpp @@ -169,6 +169,7 @@ void DecalGunshot( TraceResult *pTrace, int iBulletType ) case BULLET_MONSTER_MP5: case BULLET_PLAYER_BUCKSHOT: case BULLET_PLAYER_357: + case BULLET_PLAYER_SNIPER: default: // smoke and decal UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) ); @@ -351,6 +352,18 @@ void W_Precache( void ) // hornetgun UTIL_PrecacheOtherWeapon( "weapon_hornetgun" ); + // pipe + UTIL_PrecacheOtherWeapon( "weapon_pipe" ); + + // sniper + UTIL_PrecacheOtherWeapon( "weapon_sniper" ); + + // kevlar + UTIL_PrecacheOther( "item_bodyarmour" ); + + // flashlight + UTIL_PrecacheOther( "item_flashlight" ); + if( g_pGameRules->IsDeathmatch() ) { UTIL_PrecacheOther( "weaponbox" );// container for dropped deathmatch weapons @@ -621,7 +634,14 @@ void CBasePlayerWeapon::ItemPostFrame( void ) m_pPlayer->TabulateAmmo(); SecondaryAttack(); - m_pPlayer->pev->button &= ~IN_ATTACK2; + if( !FClassnameIs( pev, "weapon_9mmhandgun" ) ) + { + m_pPlayer->pev->button &= ~IN_ATTACK2; + } + else + { + m_flNextPrimaryAttack = ( UseDecrement() ? 0.0 : gpGlobals->time ) + 0.2f; + } } else if( ( m_pPlayer->pev->button & IN_ATTACK ) && CanAttack( m_flNextPrimaryAttack, gpGlobals->time, UseDecrement() ) ) { @@ -1527,3 +1547,10 @@ TYPEDESCRIPTION CSatchel::m_SaveData[] = }; IMPLEMENT_SAVERESTORE( CSatchel, CBasePlayerWeapon ) + +TYPEDESCRIPTION CPython::m_SaveData[] = +{ + DEFINE_FIELD( CPython, m_flSoundDelay, FIELD_TIME ), +}; + +IMPLEMENT_SAVERESTORE( CPython, CBasePlayerWeapon ) diff --git a/dlls/weapons.h b/dlls/weapons.h index 5112254a..b9739e79 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -61,22 +61,25 @@ public: #define ITEM_SECURITY 3 #define ITEM_BATTERY 4 -#define WEAPON_NONE 0 +#define WEAPON_NONE 0 #define WEAPON_CROWBAR 1 -#define WEAPON_GLOCK 2 -#define WEAPON_PYTHON 3 -#define WEAPON_MP5 4 -#define WEAPON_CHAINGUN 5 -#define WEAPON_CROSSBOW 6 -#define WEAPON_SHOTGUN 7 -#define WEAPON_RPG 8 -#define WEAPON_GAUSS 9 -#define WEAPON_EGON 10 -#define WEAPON_HORNETGUN 11 -#define WEAPON_HANDGRENADE 12 -#define WEAPON_TRIPMINE 13 -#define WEAPON_SATCHEL 14 -#define WEAPON_SNARK 15 +#define WEAPON_PIPE 2 +#define WEAPON_GLOCK 3 +#define WEAPON_PYTHON 4 +#define WEAPON_MP5 5 +#define WEAPON_CHAINGUN 6 +#define WEAPON_CROSSBOW 7 +#define WEAPON_SNIPER 8 +#define WEAPON_SHOTGUN 9 +#define WEAPON_RPG 10 +#define WEAPON_GAUSS 11 +#define WEAPON_EGON 12 +#define WEAPON_HORNETGUN 13 +#define WEAPON_HANDGRENADE 14 +#define WEAPON_TRIPMINE 15 +#define WEAPON_SATCHEL 16 +#define WEAPON_SNARK 17 +#define WEAPON_FLASHLIGHT 30 #define WEAPON_ALLWEAPONS (~(1<body ) + { + default: + case ZOMBIE_BODY_SCIENTIST: + SET_MODEL( ENT( pev ), "models/zombie.mdl" ); + break; + case ZOMBIE_BODY_BARNEY: + SET_MODEL( ENT( pev ), "models/zombie_barney.mdl" ); + break; + case ZOMBIE_BODY_SOLDIER: + SET_MODEL( ENT( pev ), "models/zombie_soldier.mdl" ); + break; + } + UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX ); pev->solid = SOLID_SLIDEBOX; @@ -287,6 +307,8 @@ void CZombie::Precache() int i; PRECACHE_MODEL( "models/zombie.mdl" ); + PRECACHE_MODEL( "models/zombie_barney.mdl" ); + PRECACHE_MODEL( "models/zombie_soldier.mdl" ); for( i = 0; i < ARRAYSIZE( pAttackHitSounds ); i++ ) PRECACHE_SOUND( (char *)pAttackHitSounds[i] );