mirror of https://github.com/FWGS/hlsdk-xash3d
Merge @malortie's patches for "They Hunger".
This commit is contained in:
parent
21317e7da3
commit
c6916f1ec2
|
@ -0,0 +1,100 @@
|
|||
/***
|
||||
*
|
||||
* 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 "parsemsg.h"
|
||||
#include "ammohistory.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
DECLARE_MESSAGE(m_Zoom, Zoom)
|
||||
|
||||
int CHudZoom::Init(void)
|
||||
{
|
||||
m_fOn = 0;
|
||||
m_pWeapon = NULL;
|
||||
|
||||
HOOK_MESSAGE(Zoom);
|
||||
|
||||
m_iFlags |= HUD_ACTIVE;
|
||||
|
||||
gHUD.AddHudElem(this);
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
void CHudZoom::Reset(void)
|
||||
{
|
||||
m_fOn = 0;
|
||||
}
|
||||
|
||||
int CHudZoom::VidInit(void)
|
||||
{
|
||||
m_pWeapon = NULL;
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
int CHudZoom::MsgFunc_Zoom(const char *pszName, int iSize, void *pbuf)
|
||||
{
|
||||
int iId;
|
||||
|
||||
BEGIN_READ(pbuf, iSize);
|
||||
m_fOn = READ_BYTE();
|
||||
iId = READ_BYTE();
|
||||
|
||||
WEAPON* pWeapon = gWR.GetWeapon(iId);
|
||||
if (pWeapon)
|
||||
{
|
||||
m_pWeapon = pWeapon;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CHudZoom::Draw(float flTime)
|
||||
{
|
||||
if (gHUD.m_iHideHUDDisplay & HIDEHUD_ALL)
|
||||
return 1;
|
||||
|
||||
if (!m_fOn)
|
||||
{
|
||||
if (m_pWeapon)
|
||||
{
|
||||
SetCrosshair(m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int r, g, b, a;
|
||||
|
||||
r = b = 0;
|
||||
g = 128;
|
||||
a = 192;
|
||||
|
||||
ScaleColors(r, g, b, a);
|
||||
|
||||
FillRGBA(0, 0, ScreenWidth, ScreenHeight, r, g, b, a);
|
||||
|
||||
if (m_pWeapon)
|
||||
{
|
||||
SetCrosshair(m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "ammohistory.h"
|
||||
|
||||
extern bool bIsMultiplayer( void );
|
||||
|
||||
WEAPON *gpActiveSel; // NULL means off, 1 means just the menu bar, otherwise
|
||||
// this points to the active weapon menu item
|
||||
WEAPON *gpLastSel; // Last weapon menu selection
|
||||
|
@ -542,8 +544,17 @@ int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf )
|
|||
}
|
||||
else
|
||||
{
|
||||
if ( m_pWeapon )
|
||||
SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 );
|
||||
if( m_pWeapon )
|
||||
{
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 0, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -608,18 +619,53 @@ int CHudAmmo::MsgFunc_CurWeapon( const char *pszName, int iSize, void *pbuf )
|
|||
{
|
||||
// normal crosshairs
|
||||
if( fOnTarget && m_pWeapon->hAutoaim )
|
||||
SetCrosshair( m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 255, 255 );
|
||||
{
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
SetCrosshair( m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 255, 255 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCrosshair( m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 0, 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 );
|
||||
{
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 0, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// zoomed crosshairs
|
||||
if( fOnTarget && m_pWeapon->hZoomedAutoaim )
|
||||
SetCrosshair( m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 255, 255 );
|
||||
{
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
SetCrosshair( m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 255, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCrosshair( m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
SetCrosshair( m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 255, 255 );
|
||||
|
||||
{
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
SetCrosshair( m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 255, 255 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCrosshair( m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 0, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_fFade = 200.0f; //!!!
|
||||
|
@ -859,7 +905,14 @@ int CHudAmmo::Draw( float flTime )
|
|||
if( m_fFade > 0 )
|
||||
m_fFade -= ( gHUD.m_flTimeDelta * 20 );
|
||||
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
}
|
||||
else
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_REDISH );
|
||||
}
|
||||
|
||||
ScaleColors( r, g, b, a );
|
||||
|
||||
|
@ -887,7 +940,14 @@ int CHudAmmo::Draw( float flTime )
|
|||
|
||||
x += AmmoWidth / 2;
|
||||
|
||||
UnpackRGB( r,g,b, RGB_YELLOWISH );
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
}
|
||||
else
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_REDISH );
|
||||
}
|
||||
|
||||
// draw the | bar
|
||||
FillRGBA( x, y, iBarWidth, gHUD.m_iFontHeight, r, g, b, a );
|
||||
|
@ -957,7 +1017,7 @@ int DrawBar( int x, int y, int width, int height, float f )
|
|||
width -= w;
|
||||
}
|
||||
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
UnpackRGB( r, g, b, RGB_REDISH );
|
||||
|
||||
FillRGBA( x, y, width, height, r, g, b, 128 );
|
||||
|
||||
|
|
|
@ -71,63 +71,5 @@ int CHudBattery::MsgFunc_Battery( const char *pszName, int iSize, void *pbuf )
|
|||
|
||||
int CHudBattery::Draw( float flTime )
|
||||
{
|
||||
if( gHUD.m_iHideHUDDisplay & HIDEHUD_HEALTH )
|
||||
return 1;
|
||||
|
||||
int r, g, b, x, y, a;
|
||||
wrect_t rc;
|
||||
|
||||
rc = *m_prc2;
|
||||
rc.top += m_iHeight * ( (float)( 100 - ( min( 100,m_iBat ) ) ) * 0.01 ); // battery can go from 0 to 100 so * 0.01 goes from 0 to 1
|
||||
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
|
||||
if( !( gHUD.m_iWeaponBits & ( 1 << ( WEAPON_SUIT ) ) ) )
|
||||
return 1;
|
||||
|
||||
// Has health changed? Flash the health #
|
||||
if( m_fFade )
|
||||
{
|
||||
if( m_fFade > FADE_TIME )
|
||||
m_fFade = FADE_TIME;
|
||||
|
||||
m_fFade -= ( gHUD.m_flTimeDelta * 20 );
|
||||
if( m_fFade <= 0 )
|
||||
{
|
||||
a = 128;
|
||||
m_fFade = 0;
|
||||
}
|
||||
|
||||
// Fade the health number back to dim
|
||||
a = MIN_ALPHA + ( m_fFade / FADE_TIME ) * 128;
|
||||
}
|
||||
else
|
||||
a = MIN_ALPHA;
|
||||
|
||||
ScaleColors( r, g, b, a );
|
||||
|
||||
int iOffset = ( m_prc1->bottom - m_prc1->top ) / 6;
|
||||
|
||||
y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight / 2;
|
||||
x = ScreenWidth / 5;
|
||||
|
||||
// make sure we have the right sprite handles
|
||||
if( !m_hSprite1 )
|
||||
m_hSprite1 = gHUD.GetSprite( gHUD.GetSpriteIndex( "suit_empty" ) );
|
||||
if( !m_hSprite2 )
|
||||
m_hSprite2 = gHUD.GetSprite( gHUD.GetSpriteIndex( "suit_full" ) );
|
||||
|
||||
SPR_Set( m_hSprite1, r, g, b );
|
||||
SPR_DrawAdditive( 0, x, y - iOffset, m_prc1 );
|
||||
|
||||
if( rc.bottom > rc.top )
|
||||
{
|
||||
SPR_Set( m_hSprite2, r, g, b );
|
||||
SPR_DrawAdditive( 0, x, y - iOffset + ( rc.top - m_prc2->top ), &rc );
|
||||
}
|
||||
|
||||
x += ( m_prc1->right - m_prc1->left );
|
||||
x = gHUD.DrawHudNumber( x, y, DHN_3DIGITS | DHN_DRAWZERO, m_iBat, r, g, b );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,16 @@ 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_Shovel( struct event_args_s *args );
|
||||
void EV_Spanner( struct event_args_s *args );
|
||||
void EV_Medkit( struct event_args_s *args );
|
||||
void EV_FireAP9( struct event_args_s *args );
|
||||
void EV_FireChaingun1( struct event_args_s *args );
|
||||
void EV_FireChaingun2( struct event_args_s *args );
|
||||
void EV_FireSniper( struct event_args_s *args );
|
||||
void EV_FireSniper2( struct event_args_s *args );
|
||||
void EV_FireTaurus( struct event_args_s *args );
|
||||
}
|
||||
|
||||
#define VECTOR_CONE_1DEGREES Vector( 0.00873, 0.00873, 0.00873 )
|
||||
|
@ -317,6 +327,10 @@ void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType )
|
|||
case BULLET_MONSTER_MP5:
|
||||
case BULLET_PLAYER_BUCKSHOT:
|
||||
case BULLET_PLAYER_357:
|
||||
case BULLET_PLAYER_AP9:
|
||||
case BULLET_PLAYER_CHAINGUN:
|
||||
case BULLET_PLAYER_SNIPER:
|
||||
case BULLET_PLAYER_TAURUS:
|
||||
default:
|
||||
// smoke and decal
|
||||
EV_HLDM_GunshotDecalTrace( pTrace, EV_HLDM_DamageDecal( pe ) );
|
||||
|
@ -448,6 +462,21 @@ void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int
|
|||
EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
|
||||
EV_HLDM_DecalGunshot( &tr, iBulletType );
|
||||
break;
|
||||
case BULLET_PLAYER_AP9:
|
||||
EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
|
||||
EV_HLDM_DecalGunshot( &tr, iBulletType );
|
||||
break;
|
||||
case BULLET_PLAYER_CHAINGUN:
|
||||
EV_HLDM_DecalGunshot( &tr, iBulletType );
|
||||
break;
|
||||
case BULLET_PLAYER_SNIPER:
|
||||
EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
|
||||
EV_HLDM_DecalGunshot( &tr, iBulletType );
|
||||
break;
|
||||
case BULLET_PLAYER_TAURUS:
|
||||
EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType );
|
||||
EV_HLDM_DecalGunshot( &tr, iBulletType );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -464,7 +493,9 @@ void EV_FireGlock1( event_args_t *args )
|
|||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t velocity;
|
||||
int body;
|
||||
int empty;
|
||||
int silencerOn;
|
||||
|
||||
vec3_t ShellVelocity;
|
||||
vec3_t ShellOrigin;
|
||||
|
@ -477,24 +508,44 @@ void EV_FireGlock1( event_args_t *args )
|
|||
VectorCopy( args->angles, angles );
|
||||
VectorCopy( args->velocity, velocity );
|
||||
|
||||
body = args->iparam1;
|
||||
empty = args->bparam1;
|
||||
silencerOn = args->bparam2;
|
||||
|
||||
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, 2 );
|
||||
if( !silencerOn )
|
||||
EV_MuzzleFlash();
|
||||
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( empty ? GLOCK_SHOOT_EMPTY : GLOCK_SHOOT, body );
|
||||
|
||||
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 );
|
||||
EV_EjectBrass( ShellOrigin, ShellVelocity, angles[ YAW ], shell, TE_BOUNCE_SHELL );
|
||||
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/pl_gun3.wav", gEngfuncs.pfnRandomFloat( 0.92, 1.0 ), ATTN_NORM, 0, 98 + gEngfuncs.pfnRandomLong( 0, 3 ) );
|
||||
if( !silencerOn )
|
||||
{
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/pl_gun3.wav", gEngfuncs.pfnRandomFloat( 0.92, 1.0 ), ATTN_NORM, 0, 98 + gEngfuncs.pfnRandomLong( 0, 3 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( gEngfuncs.pfnRandomLong( 0, 1 ) )
|
||||
{
|
||||
case 0:
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/pl_gun1.wav", gEngfuncs.pfnRandomFloat( 0.8, 0.9 ), ATTN_NORM, 0, PITCH_NORM );
|
||||
break;
|
||||
case 1:
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/pl_gun2.wav", gEngfuncs.pfnRandomFloat( 0.8, 0.9 ), ATTN_NORM, 0, PITCH_NORM );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EV_GetGunPosition( args, vecSrc, origin );
|
||||
|
||||
|
@ -505,47 +556,11 @@ void EV_FireGlock1( event_args_t *args )
|
|||
|
||||
void EV_FireGlock2( event_args_t *args )
|
||||
{
|
||||
int idx;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t velocity;
|
||||
cl_entity_t *viewent = gEngfuncs.GetViewModel();
|
||||
if( !viewent )
|
||||
return;
|
||||
|
||||
vec3_t ShellVelocity;
|
||||
vec3_t ShellOrigin;
|
||||
int shell;
|
||||
vec3_t vecSrc, vecAiming;
|
||||
vec3_t vecSpread;
|
||||
vec3_t up, right, forward;
|
||||
|
||||
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( GLOCK_SHOOT, 2 );
|
||||
|
||||
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/pl_gun3.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, &tracerCount[idx - 1], args->fparam1, args->fparam2 );
|
||||
viewent->curstate.body = args->iparam1;
|
||||
}
|
||||
//======================
|
||||
// GLOCK END
|
||||
|
@ -1411,114 +1426,23 @@ BEAM *pBeam;
|
|||
BEAM *pBeam2;
|
||||
|
||||
void EV_EgonFire( event_args_t *args )
|
||||
{
|
||||
int idx, iFireState, iFireMode;
|
||||
vec3_t origin;
|
||||
|
||||
idx = args->entindex;
|
||||
VectorCopy( args->origin, origin );
|
||||
iFireState = args->iparam1;
|
||||
iFireMode = args->iparam2;
|
||||
int iStartup = args->bparam1;
|
||||
|
||||
if( iStartup )
|
||||
{
|
||||
if( iFireMode == FIRE_WIDE )
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, EGON_SOUND_STARTUP, 0.98, ATTN_NORM, 0, 125 );
|
||||
else
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, EGON_SOUND_STARTUP, 0.9, ATTN_NORM, 0, 100 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( iFireMode == FIRE_WIDE )
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_STATIC, EGON_SOUND_RUN, 0.98, ATTN_NORM, 0, 125 );
|
||||
else
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_STATIC, EGON_SOUND_RUN, 0.9, ATTN_NORM, 0, 100 );
|
||||
}
|
||||
|
||||
//Only play the weapon anims if I shot it.
|
||||
if( EV_IsLocal( idx ) )
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation ( g_fireAnims1[gEngfuncs.pfnRandomLong( 0, 3 )], 1 );
|
||||
|
||||
if( iStartup == 1 && EV_IsLocal( idx ) && !pBeam && !pBeam2 && cl_lw->value ) //Adrian: Added the cl_lw check for those lital people that hate weapon prediction.
|
||||
{
|
||||
vec3_t vecSrc, vecEnd, angles, forward, right, up;
|
||||
pmtrace_t tr;
|
||||
|
||||
cl_entity_t *pl = gEngfuncs.GetEntityByIndex( idx );
|
||||
|
||||
if( pl )
|
||||
{
|
||||
VectorCopy( gHUD.m_vecAngles, angles );
|
||||
|
||||
AngleVectors( angles, forward, right, up );
|
||||
|
||||
EV_GetGunPosition( args, vecSrc, pl->origin );
|
||||
|
||||
VectorMA( vecSrc, 2048, forward, vecEnd );
|
||||
|
||||
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 );
|
||||
|
||||
gEngfuncs.pEventAPI->EV_PopPMStates();
|
||||
|
||||
int iBeamModelIndex = gEngfuncs.pEventAPI->EV_FindModelIndex( EGON_BEAM_SPRITE );
|
||||
|
||||
float r = 50.0f;
|
||||
float g = 50.0f;
|
||||
float b = 125.0f;
|
||||
|
||||
if( IEngineStudio.IsHardware() )
|
||||
{
|
||||
r /= 100.0f;
|
||||
g /= 100.0f;
|
||||
}
|
||||
|
||||
pBeam = gEngfuncs.pEfxAPI->R_BeamEntPoint( idx | 0x1000, tr.endpos, iBeamModelIndex, 99999, 3.5, 0.2, 0.7, 55, 0, 0, r, g, b );
|
||||
|
||||
if( pBeam )
|
||||
pBeam->flags |= ( FBEAM_SINENOISE );
|
||||
|
||||
pBeam2 = gEngfuncs.pEfxAPI->R_BeamEntPoint( idx | 0x1000, tr.endpos, iBeamModelIndex, 99999, 5.0, 0.08, 0.7, 25, 0, 0, r, g, b );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EV_EgonStop( event_args_t *args )
|
||||
{
|
||||
int idx;
|
||||
vec3_t origin;
|
||||
|
||||
idx = args->entindex;
|
||||
VectorCopy( args->origin, origin );
|
||||
|
||||
// Play fire sound.
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/flmfire2.wav", 1, ATTN_NORM, 0, 98 + gEngfuncs.pfnRandomLong( 0, 0x04 ) );
|
||||
|
||||
gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, EGON_SOUND_RUN );
|
||||
|
||||
if( args->iparam1 )
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, EGON_SOUND_OFF, 0.98, ATTN_NORM, 0, 100 );
|
||||
|
||||
//Only play the weapon anims if I shot it.
|
||||
if( EV_IsLocal( idx ) )
|
||||
{
|
||||
if( pBeam )
|
||||
{
|
||||
pBeam->die = 0.0;
|
||||
pBeam = NULL;
|
||||
}
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( g_fireAnims1[gEngfuncs.pfnRandomLong( 0, 3 )], 1 );
|
||||
}
|
||||
|
||||
if( pBeam2 )
|
||||
{
|
||||
pBeam2->die = 0.0;
|
||||
pBeam2 = NULL;
|
||||
}
|
||||
}
|
||||
void EV_EgonStop( event_args_t *args )
|
||||
{
|
||||
}
|
||||
//======================
|
||||
// EGON END
|
||||
|
@ -1743,3 +1667,421 @@ int EV_TFC_IsAllyTeam( int iTeam1, int iTeam2 )
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//======================
|
||||
// SHOVEL START
|
||||
//======================
|
||||
enum shovel_e
|
||||
{
|
||||
SHOVEL_IDLE = 0,
|
||||
SHOVEL_DRAW,
|
||||
SHOVEL_HOLSTER,
|
||||
SHOVEL_ATTACK1HIT,
|
||||
SHOVEL_ATTACK1MISS,
|
||||
SHOVEL_ATTACK2MISS,
|
||||
SHOVEL_ATTACK2HIT,
|
||||
SHOVEL_ATTACK3MISS,
|
||||
SHOVEL_ATTACK3HIT,
|
||||
SHOVEL_IDLE2,
|
||||
SHOVEL_IDLE3
|
||||
};
|
||||
|
||||
//Only predict the miss sounds, hit sounds are still played
|
||||
//server side, so players don't get the wrong idea.
|
||||
void EV_Shovel( 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( SHOVEL_ATTACK1MISS, 1 );
|
||||
|
||||
switch( ( g_iSwing++ ) % 3 )
|
||||
{
|
||||
case 0:
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( SHOVEL_ATTACK1MISS, 1 );
|
||||
break;
|
||||
case 1:
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( SHOVEL_ATTACK2MISS, 1 );
|
||||
break;
|
||||
case 2:
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( SHOVEL_ATTACK3MISS, 1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//======================
|
||||
// SHOVEL END
|
||||
//======================
|
||||
|
||||
//======================
|
||||
// SPANNER START
|
||||
//======================
|
||||
enum spanner_e
|
||||
{
|
||||
SPANNER_IDLE = 0,
|
||||
SPANNER_ATTACK1,
|
||||
SPANNER_ATTACK2,
|
||||
SPANNER_USE,
|
||||
SPANNER_DRAW,
|
||||
SPANNER_HOLSTER
|
||||
};
|
||||
|
||||
//Only predict the miss sounds, hit sounds are still played
|
||||
//server side, so players don't get the wrong idea.
|
||||
void EV_Spanner( 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( SPANNER_ATTACK1, 1 );
|
||||
|
||||
switch( ( g_iSwing++ ) % 2 )
|
||||
{
|
||||
case 0:
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( SPANNER_ATTACK1, 1 );
|
||||
break;
|
||||
case 1:
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( SPANNER_ATTACK2, 1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//======================
|
||||
// SPANNER END
|
||||
//======================
|
||||
|
||||
//======================
|
||||
// AP9 START
|
||||
//======================
|
||||
enum ap9_e
|
||||
{
|
||||
AP9_IDLE = 0,
|
||||
AP9_RELOAD,
|
||||
AP9_DRAW,
|
||||
AP9_SHOOT1,
|
||||
AP9_SHOOT2,
|
||||
AP9_SHOOT3
|
||||
};
|
||||
|
||||
void EV_FireAP9( 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;
|
||||
int burstShot = args->bparam1;
|
||||
|
||||
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( AP9_SHOOT1 + gEngfuncs.pfnRandomLong( 0, 2 ), 1 );
|
||||
|
||||
int punch = !burstShot ? 2 : 1;
|
||||
|
||||
V_PunchAxis( 0, gEngfuncs.pfnRandomFloat( -punch, punch ) );
|
||||
}
|
||||
|
||||
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/ap9_fire.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) );
|
||||
|
||||
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_AP9, 2, &tracerCount[idx-1], args->fparam1, args->fparam2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_AP9, 2, &tracerCount[idx-1], args->fparam1, args->fparam2 );
|
||||
}
|
||||
}
|
||||
//======================
|
||||
// AP9 END
|
||||
//======================
|
||||
|
||||
//======================
|
||||
// TAURUS START
|
||||
//======================
|
||||
enum taurus_e
|
||||
{
|
||||
TAURUS_IDLE1 = 0,
|
||||
TAURUS_IDLE2,
|
||||
TAURUS_IDLE3,
|
||||
TAURUS_SHOOT,
|
||||
TAURUS_SHOOT2,
|
||||
TAURUS_SHOOT3,
|
||||
TAURUS_SHOOT_EMPTY,
|
||||
TAURUS_RELOAD,
|
||||
TAURUS_RELOAD2,
|
||||
TAURUS_DRAW,
|
||||
TAURUS_DRAW2
|
||||
};
|
||||
|
||||
void EV_FireTaurus( event_args_t *args )
|
||||
{
|
||||
int idx;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t velocity;
|
||||
|
||||
vec3_t vecSrc, vecAiming;
|
||||
vec3_t up, right, forward;
|
||||
|
||||
idx = args->entindex;
|
||||
VectorCopy( args->origin, origin );
|
||||
VectorCopy( args->angles, angles );
|
||||
VectorCopy( args->velocity, velocity );
|
||||
|
||||
AngleVectors( angles, forward, right, up );
|
||||
|
||||
if( EV_IsLocal( idx ) )
|
||||
{
|
||||
EV_MuzzleFlash();
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( TAURUS_SHOOT + gEngfuncs.pfnRandomLong( 0, 2 ), 1 );
|
||||
|
||||
V_PunchAxis( 0, -2.0 );
|
||||
}
|
||||
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/tau_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_TAURUS, 0, 0, args->fparam1, args->fparam2 );
|
||||
}
|
||||
//======================
|
||||
// TAURUS END
|
||||
//======================
|
||||
|
||||
//======================
|
||||
// SNIPER START
|
||||
//======================
|
||||
extern vec3_t ev_punchangle;
|
||||
|
||||
void EV_FireSniper( event_args_t *args )
|
||||
{
|
||||
int idx;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t velocity;
|
||||
int activity;
|
||||
|
||||
vec3_t vecSrc, vecAiming;
|
||||
vec3_t up, right, forward;
|
||||
|
||||
idx = args->entindex;
|
||||
VectorCopy( args->origin, origin );
|
||||
VectorCopy( args->angles, angles );
|
||||
VectorCopy( args->velocity, velocity );
|
||||
activity = args->iparam1;
|
||||
|
||||
AngleVectors( angles, forward, right, up);
|
||||
|
||||
if( EV_IsLocal( idx ) )
|
||||
{
|
||||
// Add muzzle flash to current weapon model
|
||||
EV_MuzzleFlash();
|
||||
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( activity, 1 );
|
||||
|
||||
// Substract additional pitch from already exisiting one.
|
||||
float pitch = ev_punchangle[PITCH];
|
||||
|
||||
pitch -= 4;
|
||||
|
||||
// Send punch angle.
|
||||
V_PunchAxis( 0, pitch );
|
||||
}
|
||||
|
||||
gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/sniper.wav", gEngfuncs.pfnRandomFloat( 0.8, 0.9 ), ATTN_NORM, 0, PITCH_NORM );
|
||||
|
||||
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
|
||||
//======================
|
||||
|
||||
//======================
|
||||
// SNIPER2 START
|
||||
//======================
|
||||
void EV_FireSniper2( event_args_t *args )
|
||||
{
|
||||
}
|
||||
|
||||
//======================
|
||||
// SNIPER2 END
|
||||
//======================
|
||||
|
||||
//======================
|
||||
// CHAINGUN START
|
||||
//======================
|
||||
enum chaingun_e
|
||||
{
|
||||
CHAINGUN_IDLE = 0,
|
||||
CHAINGUN_IDLE2,
|
||||
CHAINGUN_SPINUP,
|
||||
CHAINGUN_SPINDOWN,
|
||||
CHAINGUN_FIRE,
|
||||
CHAINGUN_DRAW,
|
||||
CHAINGUN_HOLSTER
|
||||
};
|
||||
|
||||
void EV_FireChaingun1( 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;
|
||||
|
||||
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( CHAINGUN_FIRE, 1 );
|
||||
|
||||
V_PunchAxis( 0, gEngfuncs.pfnRandomFloat( -1, 1 ) );
|
||||
}
|
||||
|
||||
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/asscan2.wav", 1, ATTN_NORM, 0, 94 + gEngfuncs.pfnRandomLong( 0, 0xf ) );
|
||||
|
||||
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_CHAINGUN, 2, &tracerCount[idx - 1], args->fparam1, args->fparam2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
EV_HLDM_FireBullets( idx, forward, right, up, 1, vecSrc, vecAiming, 8192, BULLET_PLAYER_CHAINGUN, 2, &tracerCount[idx - 1], args->fparam1, args->fparam2 );
|
||||
}
|
||||
}
|
||||
|
||||
extern cvar_t *cl_forwardspeed;
|
||||
extern cvar_t *cl_backspeed;
|
||||
extern cvar_t *cl_sidespeed;
|
||||
|
||||
void EV_FireChaingun2( event_args_t *args )
|
||||
{
|
||||
static float default_forwardspeed = cl_forwardspeed->value;
|
||||
static float default_backspeed = cl_backspeed->value;
|
||||
static float default_sidespeed = cl_sidespeed->value;
|
||||
|
||||
// Toggle speed.
|
||||
int idx;
|
||||
int firing;
|
||||
|
||||
idx = args->entindex;
|
||||
firing = args->bparam1;
|
||||
|
||||
if( firing )
|
||||
{
|
||||
cl_forwardspeed->value = 100;
|
||||
cl_backspeed->value = 100;
|
||||
cl_sidespeed->value = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
cl_forwardspeed->value = default_forwardspeed;
|
||||
cl_backspeed->value = default_backspeed;
|
||||
cl_sidespeed->value = default_sidespeed;
|
||||
}
|
||||
}
|
||||
//======================
|
||||
// CHAINGUN END
|
||||
//======================
|
||||
|
||||
//======================
|
||||
// MEDKIT START
|
||||
//======================
|
||||
enum medkit_e
|
||||
{
|
||||
MEDKIT_IDLE = 0,
|
||||
MEDKIT_LONGIDLE,
|
||||
MEDKIT_LONGUSE,
|
||||
MEDKIT_SHORTUSE,
|
||||
MEDKIT_HOLSTER,
|
||||
MEDKIT_DRAW
|
||||
};
|
||||
|
||||
//Only predict the miss sounds, hit sounds are still played
|
||||
//server side, so players don't get the wrong idea.
|
||||
void EV_Medkit( event_args_t *args )
|
||||
{
|
||||
int idx;
|
||||
|
||||
idx = args->entindex;
|
||||
|
||||
if( EV_IsLocal( idx ) )
|
||||
{
|
||||
gEngfuncs.pEventAPI->EV_WeaponAnimation( MEDKIT_LONGUSE, 1 );
|
||||
}
|
||||
}
|
||||
//======================
|
||||
// MEDKIT END
|
||||
//======================
|
||||
|
|
|
@ -17,7 +17,10 @@ typedef enum
|
|||
BULLET_PLAYER_357, // python
|
||||
BULLET_PLAYER_BUCKSHOT, // shotgun
|
||||
BULLET_PLAYER_CROWBAR, // crowbar swipe
|
||||
|
||||
BULLET_PLAYER_AP9,
|
||||
BULLET_PLAYER_CHAINGUN,
|
||||
BULLET_PLAYER_SNIPER,
|
||||
BULLET_PLAYER_TAURUS,
|
||||
BULLET_MONSTER_9MM,
|
||||
BULLET_MONSTER_MP5,
|
||||
BULLET_MONSTER_12MM
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern bool bIsMultiplayer( void );
|
||||
|
||||
DECLARE_MESSAGE( m_Flash, FlashBat )
|
||||
DECLARE_MESSAGE( m_Flash, Flashlight )
|
||||
|
||||
|
@ -114,10 +116,17 @@ int CHudFlashlight::Draw( float flTime )
|
|||
else
|
||||
a = MIN_ALPHA;
|
||||
|
||||
if( m_flBat < 0.20 )
|
||||
UnpackRGB( r,g,b, RGB_REDISH );
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
if( m_flBat < 0.20 )
|
||||
UnpackRGB( r, g, b, RGB_REDISH );
|
||||
else
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
}
|
||||
else
|
||||
UnpackRGB( r,g,b, RGB_YELLOWISH );
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_REDISH );
|
||||
}
|
||||
|
||||
ScaleColors( r, g, b, a );
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "mobility_int.h"
|
||||
|
||||
extern bool bIsMultiplayer( void );
|
||||
|
||||
DECLARE_MESSAGE( m_Health, Health )
|
||||
DECLARE_MESSAGE( m_Health, Damage )
|
||||
|
||||
|
@ -165,7 +167,14 @@ void CHudHealth::GetPainColor( int &r, int &g, int &b )
|
|||
#else
|
||||
if( m_iHealth > 25 )
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
}
|
||||
else
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_REDISH );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -226,12 +235,6 @@ int CHudHealth::Draw( float flTime )
|
|||
x = CrossWidth + HealthWidth / 2;
|
||||
|
||||
x = gHUD.DrawHudNumber( x, y, DHN_3DIGITS | DHN_DRAWZERO, m_iHealth, r, g, b );
|
||||
|
||||
x += HealthWidth / 2;
|
||||
|
||||
int iHeight = gHUD.m_iFontHeight;
|
||||
int iWidth = HealthWidth / 10;
|
||||
FillRGBA( x, y, iWidth, iHeight, 255, 160, 0, a );
|
||||
}
|
||||
|
||||
DrawDamage( flTime );
|
||||
|
@ -379,6 +382,15 @@ int CHudHealth::DrawDamage( float flTime )
|
|||
if( !m_bitsDamage )
|
||||
return 1;
|
||||
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
}
|
||||
else
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_REDISH );
|
||||
}
|
||||
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
|
||||
a = (int)( fabs( sin( flTime * 2 ) ) * 256.0 );
|
||||
|
|
|
@ -98,6 +98,10 @@ CGrenade *CGrenade::ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vec
|
|||
CGrenade *CGrenade::ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ){ return 0; }
|
||||
void CGrenade::DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ){ }
|
||||
|
||||
// CTnt Stubs
|
||||
void CTnt::Spawn( void ) { }
|
||||
CGrenade *CTnt::ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time ){ return 0; }
|
||||
|
||||
void UTIL_Remove( CBaseEntity *pEntity ){ }
|
||||
struct skilldata_t gSkillData;
|
||||
void UTIL_SetSize( entvars_t *pev, const Vector &vecMin, const Vector &vecMax ){ }
|
||||
|
@ -314,6 +318,7 @@ int CBasePlayerItem::Restore( class CRestore & ) { return 1; }
|
|||
int CBasePlayerItem::Save( class CSave & ) { return 1; }
|
||||
int CBasePlayerWeapon::Restore( class CRestore & ) { return 1; }
|
||||
int CBasePlayerWeapon::Save( class CSave & ) { return 1; }
|
||||
float CBasePlayerWeapon::GetNextAttackDelay( float flTime ) { return flTime; }
|
||||
void CBasePlayerItem::SetObjectCollisionBox( void ) { }
|
||||
void CBasePlayerItem::FallInit( void ) { }
|
||||
void CBasePlayerItem::FallThink( void ) { }
|
||||
|
|
|
@ -40,6 +40,16 @@ 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_Shovel( struct event_args_s *args );
|
||||
void EV_Spanner( struct event_args_s *args );
|
||||
void EV_Medkit( struct event_args_s *args );
|
||||
void EV_FireAP9( struct event_args_s *args );
|
||||
void EV_FireChaingun1( struct event_args_s *args );
|
||||
void EV_FireChaingun2( struct event_args_s *args );
|
||||
void EV_FireSniper( struct event_args_s *args );
|
||||
void EV_FireSniper2( struct event_args_s *args );
|
||||
void EV_FireTaurus( struct event_args_s *args );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -76,4 +86,14 @@ 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/shovel.sc", EV_Shovel );
|
||||
gEngfuncs.pfnHookEvent( "events/spanner.sc", EV_Spanner );
|
||||
gEngfuncs.pfnHookEvent( "events/medkit.sc", EV_Medkit );
|
||||
gEngfuncs.pfnHookEvent( "events/ap9.sc", EV_FireAP9 );
|
||||
gEngfuncs.pfnHookEvent( "events/chaingun1.sc", EV_FireChaingun1 );
|
||||
gEngfuncs.pfnHookEvent( "events/chaingun2.sc", EV_FireChaingun2 );
|
||||
gEngfuncs.pfnHookEvent( "events/sniper.sc", EV_FireSniper );
|
||||
gEngfuncs.pfnHookEvent( "events/sniper2.sc", EV_FireSniper2 );
|
||||
gEngfuncs.pfnHookEvent( "events/taurus.sc", EV_FireTaurus );
|
||||
}
|
||||
|
|
|
@ -68,6 +68,15 @@ CSatchel g_Satchel;
|
|||
CTripmine g_Tripmine;
|
||||
CSqueak g_Snark;
|
||||
|
||||
CShovel g_Shovel;
|
||||
CSpanner g_Spanner;
|
||||
CAP9 g_AP9;
|
||||
CTaurus g_Taurus;
|
||||
CHKG36 g_HKG36;
|
||||
CEinar1 g_Einar1;
|
||||
CChaingun g_Chaingun;
|
||||
CMedkit g_Medkit;
|
||||
|
||||
/*
|
||||
======================
|
||||
AlertMessage
|
||||
|
@ -637,6 +646,14 @@ void HUD_InitClientWeapons( void )
|
|||
HUD_PrepEntity( &g_Satchel, &player );
|
||||
HUD_PrepEntity( &g_Tripmine, &player );
|
||||
HUD_PrepEntity( &g_Snark, &player );
|
||||
HUD_PrepEntity( &g_Shovel, &player );
|
||||
HUD_PrepEntity( &g_Spanner, &player );
|
||||
HUD_PrepEntity( &g_AP9, &player );
|
||||
HUD_PrepEntity( &g_Taurus, &player );
|
||||
HUD_PrepEntity( &g_HKG36, &player );
|
||||
HUD_PrepEntity( &g_Einar1, &player );
|
||||
HUD_PrepEntity( &g_Chaingun, &player );
|
||||
HUD_PrepEntity( &g_Medkit, &player );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -742,6 +759,30 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
|
|||
case WEAPON_SNARK:
|
||||
pWeapon = &g_Snark;
|
||||
break;
|
||||
case WEAPON_SHOVEL:
|
||||
pWeapon = &g_Shovel;
|
||||
break;
|
||||
case WEAPON_SPANNER:
|
||||
pWeapon = &g_Spanner;
|
||||
break;
|
||||
case WEAPON_AP9:
|
||||
pWeapon = &g_AP9;
|
||||
break;
|
||||
case WEAPON_TAURUS:
|
||||
pWeapon = &g_Taurus;
|
||||
break;
|
||||
case WEAPON_HKG36:
|
||||
pWeapon = &g_HKG36;
|
||||
break;
|
||||
case WEAPON_EINAR1:
|
||||
pWeapon = &g_Einar1;
|
||||
break;
|
||||
case WEAPON_CHAINGUN:
|
||||
pWeapon = &g_Chaingun;
|
||||
break;
|
||||
case WEAPON_MEDKIT:
|
||||
pWeapon = &g_Medkit;
|
||||
break;
|
||||
}
|
||||
|
||||
// Store pointer to our destination entity_state_t so we can get our origin, etc. from it
|
||||
|
@ -851,6 +892,18 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
|
|||
( (CRpg *)player.m_pActiveItem )->m_fSpotActive = (int)from->client.vuser2[1];
|
||||
( (CRpg *)player.m_pActiveItem )->m_cActiveRockets = (int)from->client.vuser2[2];
|
||||
}
|
||||
else if( player.m_pActiveItem->m_iId== WEAPON_AP9 )
|
||||
{
|
||||
player.ammo_ap9 = (int)from->client.vuser1[1];
|
||||
}
|
||||
else if( player.m_pActiveItem->m_iId == WEAPON_TAURUS )
|
||||
{
|
||||
player.ammo_taurus = (int)from->client.vuser1[1];
|
||||
}
|
||||
else if( player.m_pActiveItem->m_iId == WEAPON_EINAR1 || player.m_pActiveItem->m_iId == WEAPON_HKG36 )
|
||||
{
|
||||
player.ammo_sniper = (int)from->client.vuser1[1];
|
||||
}
|
||||
|
||||
// Don't go firing anything if we have died.
|
||||
// Or if we don't have a weapon model deployed
|
||||
|
@ -919,6 +972,18 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
|
|||
from->client.vuser2[1] = ( (CRpg *)player.m_pActiveItem)->m_fSpotActive;
|
||||
from->client.vuser2[2] = ( (CRpg *)player.m_pActiveItem)->m_cActiveRockets;
|
||||
}
|
||||
else if( player.m_pActiveItem->m_iId == WEAPON_AP9 )
|
||||
{
|
||||
from->client.vuser1[1] = player.ammo_ap9;
|
||||
}
|
||||
else if( player.m_pActiveItem->m_iId == WEAPON_TAURUS )
|
||||
{
|
||||
from->client.vuser1[1] = player.ammo_taurus;
|
||||
}
|
||||
else if( player.m_pActiveItem->m_iId == WEAPON_EINAR1 || player.m_pActiveItem->m_iId == WEAPON_HKG36 )
|
||||
{
|
||||
from->client.vuser1[1] = player.ammo_sniper;
|
||||
}
|
||||
|
||||
// Make sure that weapon animation matches what the game .dll is telling us
|
||||
// over the wire ( fixes some animation glitches )
|
||||
|
@ -934,6 +999,9 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm
|
|||
if( pWeapon == &g_Python && bIsMultiplayer() )
|
||||
body = 1;
|
||||
|
||||
if( pWeapon == &g_Glock && ( (CGlock*)pWeapon )->m_fSilencerOn )
|
||||
body = 1;
|
||||
|
||||
// Force a fixed anim down to viewmodel
|
||||
HUD_SendWeaponAnim( to->client.weaponanim, body, 1 );
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@ void CHud::Init( void )
|
|||
m_AmmoSecondary.Init();
|
||||
m_TextMessage.Init();
|
||||
m_StatusIcons.Init();
|
||||
m_Zoom.Init();
|
||||
m_MOTD.Init();
|
||||
m_Scoreboard.Init();
|
||||
|
||||
|
@ -396,6 +397,7 @@ void CHud::VidInit( void )
|
|||
m_AmmoSecondary.VidInit();
|
||||
m_TextMessage.VidInit();
|
||||
m_StatusIcons.VidInit();
|
||||
m_Zoom.VidInit();
|
||||
m_Scoreboard.VidInit();
|
||||
m_MOTD.VidInit();
|
||||
}
|
||||
|
|
19
cl_dll/hud.h
19
cl_dll/hud.h
|
@ -556,6 +556,24 @@ private:
|
|||
icon_sprite_t m_IconList[MAX_ICONSPRITES];
|
||||
};
|
||||
|
||||
//
|
||||
//-----------------------------------------------------
|
||||
//
|
||||
|
||||
class CHudZoom : public CHudBase
|
||||
{
|
||||
public:
|
||||
int Init( void );
|
||||
int VidInit( void );
|
||||
int Draw( float flTime );
|
||||
void Reset( void );
|
||||
int MsgFunc_Zoom( const char *pszName, int iSize, void *pbuf );
|
||||
|
||||
private:
|
||||
int m_fOn;
|
||||
WEAPON* m_pWeapon;
|
||||
};
|
||||
|
||||
//
|
||||
//-----------------------------------------------------
|
||||
//
|
||||
|
@ -631,6 +649,7 @@ public:
|
|||
CHudAmmoSecondary m_AmmoSecondary;
|
||||
CHudTextMessage m_TextMessage;
|
||||
CHudStatusIcons m_StatusIcons;
|
||||
CHudZoom m_Zoom;
|
||||
CHudScoreboard m_Scoreboard;
|
||||
CHudMOTD m_MOTD;
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <stdio.h>
|
||||
#include "parsemsg.h"
|
||||
|
||||
extern bool bIsMultiplayer( void );
|
||||
|
||||
DECLARE_MESSAGE( m_Train, Train )
|
||||
|
||||
int CHudTrain::Init( void )
|
||||
|
@ -53,7 +55,15 @@ int CHudTrain::Draw( float fTime )
|
|||
{
|
||||
int r, g, b, x, y;
|
||||
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
if( bIsMultiplayer() )
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_YELLOWISH );
|
||||
}
|
||||
else
|
||||
{
|
||||
UnpackRGB( r, g, b, RGB_REDISH );
|
||||
}
|
||||
|
||||
SPR_Set( m_hSprite, r, g, b );
|
||||
|
||||
// This should show up to the right and part way up the armor number
|
||||
|
|
|
@ -1324,6 +1324,15 @@ 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_ap9.mdl", "models/v_ap9.mdl" },
|
||||
{ "models/p_hkg36.mdl", "models/v_hkg36.mdl" },
|
||||
{ "models/p_shovel.mdl", "models/v_shovel.mdl" },
|
||||
{ "models/p_sniper.mdl", "models/v_tfc_sniper.mdl" },
|
||||
{ "models/p_spanner.mdl", "models/v_tfc_spanner.mdl" },
|
||||
{ "models/p_taurus.mdl", "models/v_taurus.mdl" },
|
||||
{ "models/p_tfac.mdl", "models/v_tfac.mdl" },
|
||||
{ "models/p_tfc_medkit.mdl", "models/v_tfc_medkit.mdl" },
|
||||
{ "models/p_tnt.mdl", "models/v_tnt.mdl" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
/***
|
||||
*
|
||||
* 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 "soundent.h"
|
||||
#include "gamerules.h"
|
||||
|
||||
enum ap9_e
|
||||
{
|
||||
AP9_IDLE = 0,
|
||||
AP9_RELOAD,
|
||||
AP9_DRAW,
|
||||
AP9_SHOOT1,
|
||||
AP9_SHOOT2,
|
||||
AP9_SHOOT3,
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_th_ap9, CAP9);
|
||||
|
||||
|
||||
void CAP9::Spawn()
|
||||
{
|
||||
Precache();
|
||||
SET_MODEL(ENT(pev), "models/w_ap9.mdl");
|
||||
m_iId = WEAPON_AP9;
|
||||
|
||||
m_iDefaultAmmo = AP9_DEFAULT_GIVE;
|
||||
|
||||
m_iBurstShots = 0;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
|
||||
void CAP9::Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/v_ap9.mdl");
|
||||
PRECACHE_MODEL("models/w_ap9.mdl");
|
||||
PRECACHE_MODEL("models/p_ap9.mdl");
|
||||
|
||||
m_iShell = PRECACHE_MODEL("models/shell.mdl");// brass shellTE_MODEL
|
||||
|
||||
PRECACHE_MODEL("models/w_ap9clip.mdl");
|
||||
PRECACHE_SOUND("items/9mmclip1.wav");
|
||||
|
||||
PRECACHE_SOUND("weapons/ap9_bolt.wav");
|
||||
PRECACHE_SOUND("weapons/ap9_clipin.wav");
|
||||
PRECACHE_SOUND("weapons/ap9_clipout.wav");
|
||||
PRECACHE_SOUND("weapons/ap9_fire.wav");
|
||||
|
||||
PRECACHE_SOUND("weapons/357_cock1.wav");
|
||||
|
||||
m_usFireAP9 = PRECACHE_EVENT(1, "events/ap9.sc");
|
||||
}
|
||||
|
||||
int CAP9::GetItemInfo(ItemInfo *p)
|
||||
{
|
||||
p->pszName = STRING(pev->classname);
|
||||
p->pszAmmo1 = "ap9";
|
||||
p->iMaxAmmo1 = AP9_MAX_CARRY;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = AP9_MAX_CLIP;
|
||||
p->iSlot = 1;
|
||||
p->iPosition = 2;
|
||||
p->iFlags = 0;
|
||||
p->iId = m_iId = WEAPON_AP9;
|
||||
p->iWeight = AP9_WEIGHT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CAP9::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;
|
||||
}
|
||||
|
||||
BOOL CAP9::Deploy()
|
||||
{
|
||||
BOOL bResult = DefaultDeploy("models/v_ap9.mdl", "models/p_ap9.mdl", AP9_DRAW, "ap9");
|
||||
|
||||
if (bResult)
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.7;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
void CAP9::PrimaryAttack(void)
|
||||
{
|
||||
m_fInAttack = 0;
|
||||
|
||||
AP9Fire(0.03, 0.13, TRUE, FALSE);
|
||||
}
|
||||
|
||||
void CAP9::SecondaryAttack(void)
|
||||
{
|
||||
if (m_fInAttack != 0)
|
||||
return;
|
||||
|
||||
m_fInAttack = 1;
|
||||
m_iBurstShots = 0;
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay(2.0);
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() - 0.1;
|
||||
}
|
||||
|
||||
void CAP9::AP9Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim, BOOL fBurstShot)
|
||||
{
|
||||
if (m_iClip <= 0)
|
||||
{
|
||||
if (m_fFireOnEmpty)
|
||||
{
|
||||
PlayEmptySound();
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.2);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_iClip--;
|
||||
|
||||
m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH;
|
||||
|
||||
int flags;
|
||||
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
flags = FEV_NOTHOST;
|
||||
#else
|
||||
flags = 0;
|
||||
#endif
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
// silenced
|
||||
if (pev->body == 1)
|
||||
{
|
||||
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME;
|
||||
m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// non-silenced
|
||||
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME;
|
||||
m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH;
|
||||
}
|
||||
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition( );
|
||||
Vector vecAiming;
|
||||
|
||||
if ( fUseAutoAim )
|
||||
{
|
||||
vecAiming = m_pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
|
||||
}
|
||||
else
|
||||
{
|
||||
vecAiming = gpGlobals->v_forward;
|
||||
}
|
||||
|
||||
Vector vecDir;
|
||||
vecDir = m_pPlayer->FireBulletsPlayer( 1, vecSrc, vecAiming, Vector( flSpread, flSpread, flSpread ), 8192, BULLET_PLAYER_AP9, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed );
|
||||
|
||||
PLAYBACK_EVENT_FULL(flags, m_pPlayer->edict(), m_usFireAP9, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, fBurstShot, 0);
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay(flCycleTime);
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
|
||||
}
|
||||
|
||||
void CAP9::Reload(void)
|
||||
{
|
||||
if (m_pPlayer->ammo_ap9 <= 0)
|
||||
return;
|
||||
|
||||
int iResult = DefaultReload(AP9_MAX_CLIP, AP9_RELOAD, 2.9);
|
||||
|
||||
if (iResult)
|
||||
{
|
||||
m_fInAttack = 0;
|
||||
m_iBurstShots = 0;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAP9::WeaponIdle(void)
|
||||
{
|
||||
ResetEmptySound();
|
||||
|
||||
m_pPlayer->GetAutoaimVector(AUTOAIM_5DEGREES);
|
||||
|
||||
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
|
||||
return;
|
||||
|
||||
if (m_fInAttack != 0)
|
||||
{
|
||||
if (m_iBurstShots < 3 && m_iClip > 0)
|
||||
{
|
||||
AP9Fire(0.01, 0.05, FALSE, TRUE);
|
||||
|
||||
m_iBurstShots++;
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay(2.0f);
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.05;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fInAttack = 0;
|
||||
m_iBurstShots = 0;
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay(0.5f);
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SendWeaponAnim(AP9_IDLE);
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15); // how long till we do this again.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CAP9Ammo : public CBasePlayerAmmo
|
||||
{
|
||||
void Spawn(void)
|
||||
{
|
||||
Precache();
|
||||
SET_MODEL(ENT(pev), "models/w_ap9clip.mdl");
|
||||
CBasePlayerAmmo::Spawn();
|
||||
}
|
||||
void Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/w_ap9clip.mdl");
|
||||
PRECACHE_SOUND("items/9mmclip1.wav");
|
||||
}
|
||||
BOOL AddAmmo(CBaseEntity *pOther)
|
||||
{
|
||||
int bResult = (pOther->GiveAmmo(AMMO_AP9_GIVE, "ap9", AP9_MAX_CARRY) != -1);
|
||||
if (bResult)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM);
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS(ammo_th_ap9, CAP9Ammo);
|
|
@ -0,0 +1,173 @@
|
|||
/***
|
||||
*
|
||||
* 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 "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "squadmonster.h"
|
||||
#include "schedule.h"
|
||||
#include "effects.h"
|
||||
#include "weapons.h"
|
||||
#include "soundent.h"
|
||||
#include "islave.h"
|
||||
|
||||
|
||||
class CBabyKelly : public CISlave
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
|
||||
void DeathSound(void);
|
||||
void PainSound(void);
|
||||
void AlertSound(void);
|
||||
void IdleSound(void);
|
||||
|
||||
static const char *pAttackHitSounds[];
|
||||
static const char *pAttackMissSounds[];
|
||||
static const char *pPainSounds[];
|
||||
static const char *pDeathSounds[];
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(monster_th_babykelly, CBabyKelly);
|
||||
|
||||
|
||||
const char *CBabyKelly::pAttackHitSounds[] =
|
||||
{
|
||||
"zombie/claw_strike1.wav",
|
||||
"zombie/claw_strike2.wav",
|
||||
"zombie/claw_strike3.wav",
|
||||
};
|
||||
|
||||
const char *CBabyKelly::pAttackMissSounds[] =
|
||||
{
|
||||
"zombie/claw_miss1.wav",
|
||||
"zombie/claw_miss2.wav",
|
||||
};
|
||||
|
||||
const char *CBabyKelly::pPainSounds[] =
|
||||
{
|
||||
"aslave/slv_pain1.wav",
|
||||
"aslave/slv_pain2.wav",
|
||||
};
|
||||
|
||||
const char *CBabyKelly::pDeathSounds[] =
|
||||
{
|
||||
"aslave/slv_die1.wav",
|
||||
"aslave/slv_die2.wav",
|
||||
};
|
||||
|
||||
|
||||
//=========================================================
|
||||
// ALertSound - scream
|
||||
//=========================================================
|
||||
void CBabyKelly::AlertSound(void)
|
||||
{
|
||||
if (m_hEnemy != NULL)
|
||||
{
|
||||
SENTENCEG_PlayRndSz(ENT(pev), "BKL_ALERT", 0.85, ATTN_NORM, 0, m_voicePitch);
|
||||
|
||||
CallForHelp("monster_alien_slave", 512, m_hEnemy, m_vecEnemyLKP);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// IdleSound
|
||||
//=========================================================
|
||||
void CBabyKelly::IdleSound(void)
|
||||
{
|
||||
if (RANDOM_LONG(0, 2) == 0)
|
||||
{
|
||||
SENTENCEG_PlayRndSz(ENT(pev), "BKL_IDLE", 0.85, ATTN_NORM, 0, m_voicePitch);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// PainSound
|
||||
//=========================================================
|
||||
void CBabyKelly::PainSound(void)
|
||||
{
|
||||
if (RANDOM_LONG(0, 2) == 0)
|
||||
{
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pPainSounds), 1.0, ATTN_NORM, 0, m_voicePitch);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// DieSound
|
||||
//=========================================================
|
||||
|
||||
void CBabyKelly::DeathSound(void)
|
||||
{
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pDeathSounds), 1.0, ATTN_NORM, 0, m_voicePitch);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CBabyKelly::Spawn()
|
||||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL(ENT(pev), "models/babykelly.mdl");
|
||||
UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX);
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = DONT_BLEED;
|
||||
pev->effects = 0;
|
||||
pev->health = gSkillData.slaveHealth;
|
||||
pev->view_ofs = Vector(0, 0, 32);// position of the eyes relative to monster's origin.
|
||||
m_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so npc will notice player and say hello
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_RANGE_ATTACK2 | bits_CAP_DOORS_GROUP;
|
||||
|
||||
m_voicePitch = RANDOM_LONG(85, 110);
|
||||
|
||||
MonsterInit();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CBabyKelly::Precache()
|
||||
{
|
||||
int i;
|
||||
|
||||
PRECACHE_MODEL("models/babykelly.mdl");
|
||||
PRECACHE_MODEL("sprites/lgtning.spr");
|
||||
PRECACHE_SOUND("debris/zap1.wav");
|
||||
PRECACHE_SOUND("debris/zap4.wav");
|
||||
PRECACHE_SOUND("weapons/electro4.wav");
|
||||
PRECACHE_SOUND("hassault/hw_shoot1.wav");
|
||||
PRECACHE_SOUND("zombie/zo_pain2.wav");
|
||||
PRECACHE_SOUND("headcrab/hc_headbite.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_miss1.wav");
|
||||
|
||||
for (i = 0; i < ARRAYSIZE(pAttackHitSounds); i++)
|
||||
PRECACHE_SOUND((char *)pAttackHitSounds[i]);
|
||||
|
||||
for (i = 0; i < ARRAYSIZE(pAttackMissSounds); i++)
|
||||
PRECACHE_SOUND((char *)pAttackMissSounds[i]);
|
||||
|
||||
for (i = 0; i < ARRAYSIZE(pPainSounds); i++)
|
||||
PRECACHE_SOUND((char *)pPainSounds[i]);
|
||||
|
||||
for (i = 0; i < ARRAYSIZE(pDeathSounds); i++)
|
||||
PRECACHE_SOUND((char *)pDeathSounds[i]);
|
||||
|
||||
UTIL_PrecacheOther("test_effect");
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/***
|
||||
*
|
||||
* 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 "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "effects.h"
|
||||
#include "apache.h"
|
||||
|
||||
#define SF_WAITFORTRIGGER (0x04 | 0x40) // UNDONE: Fix!
|
||||
#define SF_NOWRECKAGE 0x08
|
||||
|
||||
class CBoss : public CApache
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
|
||||
BOOL FireGun(void);
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(monster_th_boss, CBoss);
|
||||
|
||||
void CBoss::Spawn(void)
|
||||
{
|
||||
Precache( );
|
||||
// motor
|
||||
pev->movetype = MOVETYPE_FLY;
|
||||
pev->solid = SOLID_BBOX;
|
||||
|
||||
SET_MODEL(ENT(pev), "models/boss.mdl");
|
||||
UTIL_SetSize( pev, Vector( -32, -32, -64 ), Vector( 32, 32, 0 ) );
|
||||
UTIL_SetOrigin( pev, pev->origin );
|
||||
|
||||
pev->flags |= FL_MONSTER;
|
||||
pev->takedamage = DAMAGE_AIM;
|
||||
pev->health = gSkillData.bossHealth;
|
||||
|
||||
m_flFieldOfView = -0.707; // 270 degrees
|
||||
|
||||
pev->sequence = 0;
|
||||
ResetSequenceInfo( );
|
||||
pev->frame = RANDOM_LONG(0, 0xFF);
|
||||
|
||||
InitBoneControllers();
|
||||
|
||||
if (pev->spawnflags & SF_WAITFORTRIGGER)
|
||||
{
|
||||
SetUse(&CBoss::StartupUse);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetThink(&CBoss::HuntThink);
|
||||
SetTouch(&CBoss::FlyTouch);
|
||||
pev->nextthink = gpGlobals->time + 1.0;
|
||||
}
|
||||
|
||||
m_iRockets = 0;
|
||||
}
|
||||
|
||||
|
||||
void CBoss::Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/boss.mdl");
|
||||
|
||||
PRECACHE_SOUND("apache/ap_rotor1.wav");
|
||||
PRECACHE_SOUND("apache/ap_rotor2.wav");
|
||||
PRECACHE_SOUND("apache/ap_rotor3.wav");
|
||||
PRECACHE_SOUND("apache/ap_whine1.wav");
|
||||
|
||||
PRECACHE_SOUND("weapons/mortarhit.wav");
|
||||
|
||||
m_iSpriteTexture = PRECACHE_MODEL( "sprites/white.spr" );
|
||||
|
||||
PRECACHE_SOUND("turret/tu_fire1.wav");
|
||||
|
||||
PRECACHE_MODEL("sprites/lgtning.spr");
|
||||
|
||||
m_iExplode = PRECACHE_MODEL( "sprites/fexplo.spr" );
|
||||
m_iBodyGibs = PRECACHE_MODEL( "models/metalplategibs_green.mdl" );
|
||||
}
|
||||
|
||||
BOOL CBoss::FireGun()
|
||||
{
|
||||
UTIL_MakeAimVectors( pev->angles );
|
||||
|
||||
Vector posGun, angGun;
|
||||
GetAttachment( 1, posGun, angGun );
|
||||
|
||||
Vector vecTarget = (m_posTarget - posGun).Normalize( );
|
||||
|
||||
Vector vecOut;
|
||||
|
||||
vecOut.x = DotProduct( -gpGlobals->v_right, vecTarget );
|
||||
vecOut.y = -DotProduct( gpGlobals->v_forward, vecTarget );
|
||||
vecOut.z = DotProduct( gpGlobals->v_up, vecTarget );
|
||||
|
||||
Vector angles = UTIL_VecToAngles (vecOut);
|
||||
|
||||
angles.x = -angles.x;
|
||||
if (angles.y > 180)
|
||||
angles.y = angles.y - 360;
|
||||
if (angles.y < -180)
|
||||
angles.y = angles.y + 360;
|
||||
if (angles.x > 180)
|
||||
angles.x = angles.x - 360;
|
||||
if (angles.x < -180)
|
||||
angles.x = angles.x + 360;
|
||||
|
||||
if (angles.x > m_angGun.x)
|
||||
m_angGun.x = min( angles.x, m_angGun.x + 12 );
|
||||
if (angles.x < m_angGun.x)
|
||||
m_angGun.x = max( angles.x, m_angGun.x - 12 );
|
||||
if (angles.y > m_angGun.y)
|
||||
m_angGun.y = min( angles.y, m_angGun.y + 12 );
|
||||
if (angles.y < m_angGun.y)
|
||||
m_angGun.y = max( angles.y, m_angGun.y - 12 );
|
||||
|
||||
m_angGun.y = SetBoneController( 0, m_angGun.y );
|
||||
m_angGun.x = SetBoneController( 1, m_angGun.x );
|
||||
|
||||
Vector posBarrel, angBarrel;
|
||||
GetAttachment( 0, posBarrel, angBarrel );
|
||||
Vector vecGun = (posBarrel - posGun).Normalize( );
|
||||
|
||||
if (DotProduct( vecGun, vecTarget ) > 0.98)
|
||||
{
|
||||
FireBullets( 1, posGun, vecGun, VECTOR_CONE_4DEGREES, 8192, BULLET_MONSTER_12MM, 1 );
|
||||
EMIT_SOUND(ENT(pev), CHAN_WEAPON, "turret/tu_fire1.wav", 1, 0.3);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,396 @@
|
|||
/***
|
||||
*
|
||||
* 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"
|
||||
|
||||
enum chaingun_e {
|
||||
CHAINGUN_IDLE = 0,
|
||||
CHAINGUN_IDLE2,
|
||||
CHAINGUN_SPINUP,
|
||||
CHAINGUN_SPINDOWN,
|
||||
CHAINGUN_FIRE,
|
||||
CHAINGUN_DRAW,
|
||||
CHAINGUN_HOLSTER,
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_th_chaingun, CChaingun);
|
||||
|
||||
void CChaingun::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_CHAINGUN;
|
||||
SET_MODEL(ENT(pev), "models/w_tfac.mdl");
|
||||
|
||||
m_iDefaultAmmo = CHAINGUN_DEFAULT_GIVE;
|
||||
|
||||
m_fInAttack = 0;
|
||||
m_fInSpecialReload = 0;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
|
||||
void CChaingun::Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/v_tfac.mdl");
|
||||
PRECACHE_MODEL("models/w_tfac.mdl");
|
||||
PRECACHE_MODEL("models/p_tfac.mdl");
|
||||
|
||||
m_iShell = PRECACHE_MODEL("models/shell.mdl");// brass shell
|
||||
|
||||
PRECACHE_SOUND("items/9mmclip1.wav");
|
||||
PRECACHE_SOUND("weapons/reload3.wav");
|
||||
|
||||
PRECACHE_SOUND("weapons/asscan1.wav");
|
||||
PRECACHE_SOUND("weapons/asscan2.wav");
|
||||
PRECACHE_SOUND("weapons/asscan3.wav");
|
||||
PRECACHE_SOUND("weapons/asscan4.wav");
|
||||
|
||||
m_usFireChaingun1 = PRECACHE_EVENT(1, "events/chaingun1.sc");
|
||||
m_usFireChaingun2 = PRECACHE_EVENT(1, "events/chaingun2.sc");
|
||||
}
|
||||
|
||||
int CChaingun::GetItemInfo(ItemInfo *p)
|
||||
{
|
||||
p->pszName = STRING(pev->classname);
|
||||
p->pszAmmo1 = "9mm";
|
||||
p->iMaxAmmo1 = _9MM_MAX_CARRY;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = CHAINGUN_MAX_CLIP;
|
||||
p->iSlot = 3;
|
||||
p->iPosition = 3;
|
||||
p->iFlags = 0;
|
||||
p->iId = m_iId = WEAPON_CHAINGUN;
|
||||
p->iWeight = CHAINGUN_WEIGHT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CChaingun::Deploy()
|
||||
{
|
||||
// pev->body = 1;
|
||||
return DefaultDeploy("models/v_tfac.mdl", "models/p_tfac.mdl", CHAINGUN_DRAW, "chaingun", UseDecrement());
|
||||
}
|
||||
|
||||
void CChaingun::Holster(int skiplocal /*= 0*/)
|
||||
{
|
||||
m_fInReload = FALSE;
|
||||
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1.0;
|
||||
m_flTimeWeaponIdle = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15);
|
||||
SendWeaponAnim(CHAINGUN_HOLSTER);
|
||||
|
||||
// Stop chaingun sounds.
|
||||
StopSounds();
|
||||
|
||||
m_fInAttack = 0;
|
||||
m_fInSpecialReload = 0;
|
||||
}
|
||||
|
||||
void CChaingun::PrimaryAttack(void)
|
||||
{
|
||||
// Don't fire while in reload.
|
||||
if (m_fInSpecialReload != 0)
|
||||
{
|
||||
WeaponIdle();
|
||||
return;
|
||||
}
|
||||
|
||||
// don't fire underwater
|
||||
if (m_pPlayer->pev->waterlevel == 3)
|
||||
{
|
||||
if (m_fInAttack != 0)
|
||||
{
|
||||
// spin down
|
||||
SpinDown();
|
||||
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayEmptySound();
|
||||
}
|
||||
|
||||
m_flNextSecondaryAttack = m_flNextPrimaryAttack = GetNextAttackDelay(0.5);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_iClip <= 0)
|
||||
{
|
||||
Reload();
|
||||
if (m_iClip == 0)
|
||||
PlayEmptySound();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_fInAttack == 0)
|
||||
{
|
||||
// Spin up
|
||||
SpinUp();
|
||||
}
|
||||
else if (m_fInAttack == 1)
|
||||
{
|
||||
if (m_flTimeWeaponIdle < UTIL_WeaponTimeBase())
|
||||
{
|
||||
// fire
|
||||
SendWeaponAnim(CHAINGUN_FIRE);
|
||||
m_fInAttack = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Spin
|
||||
Spin();
|
||||
}
|
||||
|
||||
m_fInSpecialReload = 0;
|
||||
}
|
||||
|
||||
void CChaingun::SecondaryAttack(void)
|
||||
{
|
||||
WeaponIdle();
|
||||
}
|
||||
|
||||
void CChaingun::Reload(void)
|
||||
{
|
||||
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == CHAINGUN_MAX_CLIP)
|
||||
return;
|
||||
|
||||
// don't reload until recoil is done
|
||||
if (m_flNextPrimaryAttack > UTIL_WeaponTimeBase())
|
||||
return;
|
||||
|
||||
if (m_fInAttack != 0)
|
||||
return;
|
||||
|
||||
// Stop sounds.
|
||||
StopSounds();
|
||||
|
||||
// Stop spin up or firing.
|
||||
m_fInAttack = 0;
|
||||
|
||||
// Restore player speed.
|
||||
PLAYBACK_EVENT_FULL(0, m_pPlayer->edict(), m_usFireChaingun2, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, FALSE, 0);
|
||||
|
||||
// check to see if we're ready to reload
|
||||
if (m_fInSpecialReload == 0)
|
||||
{
|
||||
SendWeaponAnim(CHAINGUN_HOLSTER);
|
||||
m_fInSpecialReload = 1;
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.6;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.6);
|
||||
m_flNextSecondaryAttack = GetNextAttackDelay(1.5);
|
||||
return;
|
||||
}
|
||||
else if (m_fInSpecialReload == 1)
|
||||
{
|
||||
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
|
||||
return;
|
||||
// was waiting for gun to move to side
|
||||
m_fInSpecialReload = 2;
|
||||
|
||||
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/reload3.wav", 1, ATTN_NORM, 0, 85 + RANDOM_LONG(0, 0x1f));
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.8;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( DefaultReload(SNIPER_MAX_CLIP, CHAINGUN_DRAW, 0.53 ))
|
||||
{
|
||||
m_fInSpecialReload = 3;
|
||||
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() - 0.1;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CChaingun::WeaponIdle(void)
|
||||
{
|
||||
ResetEmptySound();
|
||||
|
||||
m_pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES);
|
||||
|
||||
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
|
||||
return;
|
||||
|
||||
if (m_fInAttack != 0)
|
||||
{
|
||||
// Spin down
|
||||
SpinDown();
|
||||
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_iClip == 0 && m_fInSpecialReload == 0 && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else if (m_fInSpecialReload != 0)
|
||||
{
|
||||
if (m_iClip != CHAINGUN_MAX_CLIP && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fInSpecialReload = 0;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.5;
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay(0.0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int iAnim;
|
||||
float flRand = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 0, 1);
|
||||
if (flRand <= 0.5)
|
||||
{
|
||||
iAnim = CHAINGUN_IDLE;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + (41.0 / 10.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = CHAINGUN_IDLE2;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + (51.0 / 10.0);
|
||||
}
|
||||
SendWeaponAnim(iAnim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CChaingun::ShouldWeaponIdle(void)
|
||||
{
|
||||
return m_iClip == 0 || m_fInSpecialReload != 0;
|
||||
}
|
||||
|
||||
void CChaingun::SpinUp(void)
|
||||
{
|
||||
// spin up
|
||||
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME;
|
||||
|
||||
SendWeaponAnim(CHAINGUN_SPINUP);
|
||||
|
||||
// Slowdown player.
|
||||
PLAYBACK_EVENT_FULL(0, m_pPlayer->edict(), m_usFireChaingun2, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, TRUE, 0);
|
||||
|
||||
m_fInAttack = 1;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.5;
|
||||
|
||||
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/asscan1.wav", 1.0, ATTN_NORM, 0, 80 + RANDOM_LONG(0, 0x3f));
|
||||
}
|
||||
|
||||
void CChaingun::SpinDown(void)
|
||||
{
|
||||
// Spin down
|
||||
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME;
|
||||
|
||||
SendWeaponAnim(CHAINGUN_SPINDOWN);
|
||||
|
||||
// Restore player speed.
|
||||
PLAYBACK_EVENT_FULL(0, m_pPlayer->edict(), m_usFireChaingun2, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, FALSE, 0);
|
||||
|
||||
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/asscan3.wav", 1.0, ATTN_NORM, 0, 80 + RANDOM_LONG(0, 0x3f));
|
||||
|
||||
m_fInAttack = 0;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0;
|
||||
}
|
||||
|
||||
void CChaingun::Spin(void)
|
||||
{
|
||||
// out of ammo!
|
||||
if (m_iClip <= 0)
|
||||
{
|
||||
// Spin down
|
||||
SpinDown();
|
||||
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
m_fInAttack = 2;
|
||||
|
||||
// Spin sound.
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/asscan4.wav", 0.8, ATTN_NORM);
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
if (!bIsMultiplayer())
|
||||
#else
|
||||
if (!g_pGameRules->IsMultiplayer())
|
||||
#endif
|
||||
{
|
||||
// single player spread
|
||||
Fire(0.1, 0.1, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// optimized multiplayer. Widened to make it easier to hit a moving player
|
||||
Fire(0.2, 0.1, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void CChaingun::Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim)
|
||||
{
|
||||
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME;
|
||||
m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH;
|
||||
|
||||
m_iClip--;
|
||||
|
||||
m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH;
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition();
|
||||
Vector vecAiming = m_pPlayer->GetAutoaimVector(AUTOAIM_5DEGREES);
|
||||
Vector vecDir;
|
||||
|
||||
vecDir = m_pPlayer->FireBulletsPlayer(1, vecSrc, vecAiming, Vector(flSpread, flSpread, flSpread), 8192, BULLET_PLAYER_CHAINGUN, 2, 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_usFireChaingun1, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0);
|
||||
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(flCycleTime);
|
||||
|
||||
if (m_flNextPrimaryAttack < UTIL_WeaponTimeBase())
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + flCycleTime;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.1;
|
||||
}
|
||||
|
||||
void CChaingun::StopSounds(void)
|
||||
{
|
||||
STOP_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/asscan1.wav");
|
||||
STOP_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/asscan2.wav");
|
||||
STOP_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/asscan3.wav");
|
||||
STOP_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/asscan4.wav");
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/***
|
||||
*
|
||||
* 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 "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "schedule.h"
|
||||
#include "game.h"
|
||||
#include "headcrab.h"
|
||||
|
||||
class CChicken : public CHeadCrab
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
void StartTask(Task_t *pTask);
|
||||
|
||||
void PainSound(void);
|
||||
void DeathSound(void);
|
||||
void IdleSound(void);
|
||||
void AlertSound(void);
|
||||
void AttackSound(void);
|
||||
|
||||
static const char *pIdleSounds[];
|
||||
static const char *pAlertSounds[];
|
||||
static const char *pPainSounds[];
|
||||
static const char *pAttackSounds[];
|
||||
static const char *pDeathSounds[];
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(monster_th_chicken, CChicken);
|
||||
|
||||
const char *CChicken::pIdleSounds[] =
|
||||
{
|
||||
"chicken/ch_idle1.wav",
|
||||
"chicken/ch_idle2.wav",
|
||||
};
|
||||
const char *CChicken::pAlertSounds[] =
|
||||
{
|
||||
"chicken/ch_alert1.wav",
|
||||
"chicken/ch_alert1.wav",
|
||||
};
|
||||
const char *CChicken::pPainSounds[] =
|
||||
{
|
||||
"chicken/ch_pain1.wav",
|
||||
"chicken/ch_pain2.wav",
|
||||
};
|
||||
const char *CChicken::pAttackSounds[] =
|
||||
{
|
||||
"chicken/ch_attack1.wav",
|
||||
"chicken/ch_attack2.wav",
|
||||
};
|
||||
|
||||
const char *CChicken::pDeathSounds[] =
|
||||
{
|
||||
"chicken/ch_die1.wav",
|
||||
"chicken/ch_die2.wav",
|
||||
};
|
||||
|
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CChicken::Spawn()
|
||||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL(ENT(pev), "models/chicken.mdl");
|
||||
UTIL_SetSize(pev, Vector(-12, -12, 0), Vector(12, 12, 24));
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->effects = 0;
|
||||
pev->health = gSkillData.headcrabHealth;
|
||||
pev->view_ofs = Vector(0, 0, 20);// position of the eyes relative to monster's origin.
|
||||
pev->yaw_speed = 5;//!!! should we put this in the monster's changeanim function since turn rates may vary with state/anim?
|
||||
m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
|
||||
MonsterInit();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CChicken::Precache()
|
||||
{
|
||||
PRECACHE_SOUND_ARRAY(pIdleSounds);
|
||||
PRECACHE_SOUND_ARRAY(pAlertSounds);
|
||||
PRECACHE_SOUND_ARRAY(pPainSounds);
|
||||
PRECACHE_SOUND_ARRAY(pAttackSounds);
|
||||
PRECACHE_SOUND_ARRAY(pDeathSounds);
|
||||
|
||||
PRECACHE_MODEL("models/chicken.mdl");
|
||||
}
|
||||
|
||||
void CChicken::StartTask(Task_t *pTask)
|
||||
{
|
||||
m_iTaskStatus = TASKSTATUS_RUNNING;
|
||||
|
||||
switch (pTask->iTask)
|
||||
{
|
||||
case TASK_RANGE_ATTACK1:
|
||||
{
|
||||
EMIT_SOUND_DYN(edict(), CHAN_WEAPON, pAttackSounds[0], GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch());
|
||||
m_IdealActivity = ACT_RANGE_ATTACK1;
|
||||
SetTouch(&CHeadCrab::LeapTouch);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
CHeadCrab::StartTask(pTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// IdleSound
|
||||
//=========================================================
|
||||
void CChicken::IdleSound(void)
|
||||
{
|
||||
EMIT_SOUND_DYN(edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY(pIdleSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch());
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// AlertSound
|
||||
//=========================================================
|
||||
void CChicken::AlertSound(void)
|
||||
{
|
||||
EMIT_SOUND_DYN(edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY(pAlertSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch());
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// PainSound
|
||||
//=========================================================
|
||||
void CChicken::PainSound(void)
|
||||
{
|
||||
EMIT_SOUND_DYN(edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY(pPainSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch());
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// DeathSound
|
||||
//=========================================================
|
||||
void CChicken::DeathSound(void)
|
||||
{
|
||||
EMIT_SOUND_DYN(edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY(pDeathSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch());
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// AttackSound
|
||||
//=========================================================
|
||||
void CChicken::AttackSound(void)
|
||||
{
|
||||
EMIT_SOUND_DYN(edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY(pAttackSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch());
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/***
|
||||
*
|
||||
* 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 "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "talkmonster.h"
|
||||
#include "schedule.h"
|
||||
#include "defaultai.h"
|
||||
#include "scripted.h"
|
||||
#include "animation.h"
|
||||
#include "soundent.h"
|
||||
#include "scientist.h"
|
||||
|
||||
#define NUM_CIVILIAN_HEADS 5 // four heads available for civilian model
|
||||
enum { HEAD_GLASSES = 0, HEAD_FRANKLIN = 1, HEAD_ECHELON_OFFICER = 2, HEAD_SLICK = 3, HEAD_ORDELY = 4, };
|
||||
|
||||
class CCivilian : public CScientist
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(einar_civ, CCivilian);
|
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CCivilian::Spawn(void)
|
||||
{
|
||||
Precache( );
|
||||
|
||||
SET_MODEL(ENT(pev), "models/civ.mdl");
|
||||
UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX);
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->health = gSkillData.scientistHealth;
|
||||
pev->view_ofs = Vector ( 0, 0, 50 );// position of the eyes relative to monster's origin.
|
||||
m_flFieldOfView = VIEW_FIELD_WIDE; // NOTE: we need a wide field of view so scientists will notice player and say hello
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
|
||||
// m_flDistTooFar = 256.0;
|
||||
|
||||
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_OPEN_DOORS | bits_CAP_AUTO_DOORS | bits_CAP_USE;
|
||||
|
||||
if ( pev->body == -1 )
|
||||
{// -1 chooses a random head
|
||||
pev->body = RANDOM_LONG(0, NUM_CIVILIAN_HEADS-1);// pick a head, any head
|
||||
}
|
||||
|
||||
MonsterInit();
|
||||
SetUse( &CCivilian::FollowerUse );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CCivilian :: Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL("models/civ.mdl");
|
||||
PRECACHE_SOUND("scientist/sci_pain1.wav");
|
||||
PRECACHE_SOUND("scientist/sci_pain2.wav");
|
||||
PRECACHE_SOUND("scientist/sci_pain3.wav");
|
||||
PRECACHE_SOUND("scientist/sci_pain4.wav");
|
||||
PRECACHE_SOUND("scientist/sci_pain5.wav");
|
||||
|
||||
// every new civilian must call this, otherwise
|
||||
// when a level is loaded, nobody will talk (time is reset to 0)
|
||||
TalkInit();
|
||||
|
||||
CTalkMonster::Precache();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Dead Civilian PROP
|
||||
//=========================================================
|
||||
class CDeadCivilian : public CDeadScientist
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(einar_civ_dead, CDeadCivilian);
|
||||
|
||||
//
|
||||
// ********** DeadCivilian SPAWN **********
|
||||
//
|
||||
void CDeadCivilian::Spawn()
|
||||
{
|
||||
PRECACHE_MODEL("models/civ.mdl");
|
||||
SET_MODEL(ENT(pev), "models/civ.mdl");
|
||||
|
||||
pev->effects = 0;
|
||||
pev->sequence = 0;
|
||||
// Corpses have less health
|
||||
pev->health = 8;//gSkillData.scientistHealth;
|
||||
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
|
||||
if (pev->body == -1)
|
||||
{// -1 chooses a random head
|
||||
pev->body = RANDOM_LONG(0, NUM_CIVILIAN_HEADS - 1);// pick a head, any head
|
||||
}
|
||||
|
||||
pev->sequence = LookupSequence(m_szPoses[m_iPose]);
|
||||
if (pev->sequence == -1)
|
||||
{
|
||||
ALERT(at_console, "Dead civilian with bad pose\n");
|
||||
}
|
||||
|
||||
// pev->skin += 2; // use bloody skin -- UNDONE: Turn this back on when we have a bloody skin again!
|
||||
MonsterInitDead();
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// Sitting Civilian PROP
|
||||
//=========================================================
|
||||
class CSittingCivilian : public CSittingScientist
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(einar_civ_sit, CSittingCivilian);
|
||||
|
||||
//
|
||||
// ********** Civilian SPAWN **********
|
||||
//
|
||||
void CSittingCivilian::Spawn()
|
||||
{
|
||||
PRECACHE_MODEL("models/civ.mdl");
|
||||
SET_MODEL(ENT(pev), "models/civ.mdl");
|
||||
Precache();
|
||||
InitBoneControllers();
|
||||
|
||||
UTIL_SetSize(pev, Vector(-14, -14, 0), Vector(14, 14, 36));
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
pev->effects = 0;
|
||||
pev->health = 50;
|
||||
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
m_flFieldOfView = VIEW_FIELD_WIDE; // indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
|
||||
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD;
|
||||
|
||||
SetBits(pev->spawnflags, SF_MONSTER_PREDISASTER); // predisaster only!
|
||||
|
||||
if (pev->body == -1)
|
||||
{// -1 chooses a random head
|
||||
pev->body = RANDOM_LONG(0, NUM_CIVILIAN_HEADS - 1);// pick a head, any head
|
||||
}
|
||||
|
||||
m_baseSequence = LookupSequence("sitlookleft");
|
||||
pev->sequence = m_baseSequence + RANDOM_LONG(0, 4);
|
||||
ResetSequenceInfo();
|
||||
|
||||
SetThink(&CSittingCivilian::SittingThink);
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
|
||||
DROP_TO_FLOOR(ENT(pev));
|
||||
}
|
||||
|
||||
void CSittingCivilian::Precache(void)
|
||||
{
|
||||
m_baseSequence = LookupSequence("sitlookleft");
|
||||
TalkInit();
|
||||
}
|
|
@ -0,0 +1,538 @@
|
|||
/***
|
||||
*
|
||||
* 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"
|
||||
#include "hornet.h"
|
||||
|
||||
#define FRANKLIN_MELEE_DIST 100
|
||||
|
||||
int iFranklinMuzzleFlash;
|
||||
|
||||
//=========================================================
|
||||
// monster-specific DEFINE's
|
||||
//=========================================================
|
||||
#define GRUNT_CLIP_SIZE 36 // how many bullets in a clip? - NOTE: 3 round burst sound, so keep as 3 * x!
|
||||
#define GRUNT_VOL 0.35 // volume of grunt sounds
|
||||
#define GRUNT_ATTN ATTN_NORM // attenutation of grunt sentences
|
||||
#define HGRUNT_LIMP_HEALTH 20
|
||||
#define HGRUNT_DMG_HEADSHOT ( DMG_BULLET | DMG_CLUB ) // damage types that can kill a grunt with a single headshot.
|
||||
#define HGRUNT_NUM_HEADS 2 // how many grunt heads are there?
|
||||
#define HGRUNT_MINIMUM_HEADSHOT_DAMAGE 15 // must do at least this much damage in one shot to head to score a headshot kill
|
||||
#define HGRUNT_SENTENCE_VOLUME (float)0.35 // volume of grunt sentences
|
||||
|
||||
#define HGRUNT_9MMAR ( 1 << 0)
|
||||
#define HGRUNT_HANDGRENADE ( 1 << 1)
|
||||
#define HGRUNT_GRENADELAUNCHER ( 1 << 2)
|
||||
#define HGRUNT_SHOTGUN ( 1 << 3)
|
||||
|
||||
#define HEAD_GROUP 1
|
||||
#define HEAD_GRUNT 0
|
||||
#define HEAD_COMMANDER 1
|
||||
#define HEAD_SHOTGUN 2
|
||||
#define HEAD_M203 3
|
||||
#define GUN_GROUP 2
|
||||
#define GUN_MP5 0
|
||||
#define GUN_SHOTGUN 1
|
||||
#define GUN_NONE 2
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
//=========================================================
|
||||
#define HGRUNT_AE_RELOAD ( 2 )
|
||||
#define HGRUNT_AE_KICK ( 3 )
|
||||
#define HGRUNT_AE_BURST1 ( 4 )
|
||||
#define HGRUNT_AE_BURST2 ( 5 )
|
||||
#define HGRUNT_AE_BURST3 ( 6 )
|
||||
#define HGRUNT_AE_GREN_TOSS ( 7 )
|
||||
#define HGRUNT_AE_GREN_LAUNCH ( 8 )
|
||||
#define HGRUNT_AE_GREN_DROP ( 9 )
|
||||
#define HGRUNT_AE_CAUGHT_ENEMY ( 10) // grunt established sight with an enemy (player only) that had previously eluded the squad.
|
||||
#define HGRUNT_AE_DROP_GUN ( 11) // grunt (probably dead) is dropping his mp5.
|
||||
|
||||
class CCyberFranklin : public CHGrunt
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
int Classify(void);
|
||||
void HandleAnimEvent(MonsterEvent_t *pEvent);
|
||||
|
||||
BOOL CheckMeleeAttack1(float flDot, float flDist);
|
||||
BOOL CheckRangeAttack1(float flDot, float flDist);
|
||||
BOOL CheckRangeAttack2(float flDot, float flDist) { return FALSE; }
|
||||
void CheckAmmo(void) { }
|
||||
void SetActivity(Activity NewActivity);
|
||||
void StartTask(Task_t *pTask);
|
||||
|
||||
void AlertSound(void);
|
||||
void DeathSound(void);
|
||||
void PainSound(void);
|
||||
void AttackSound(void);
|
||||
void IdleSound(void) { }
|
||||
Vector GetGunPosition(void);
|
||||
void Shoot(void);
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
BOOL m_fCanHornetAttack;
|
||||
float m_flNextHornetAttackCheck;
|
||||
|
||||
static const char *pAttackHitSounds[];
|
||||
static const char *pAttackMissSounds[];
|
||||
static const char *pAttackSounds[];
|
||||
static const char *pDieSounds[];
|
||||
static const char *pPainSounds[];
|
||||
static const char *pIdleSounds[];
|
||||
static const char *pAlertSounds[];
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(monster_th_cyberfranklin, CCyberFranklin);
|
||||
|
||||
TYPEDESCRIPTION CCyberFranklin::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD(CCyberFranklin, m_fCanHornetAttack, FIELD_BOOLEAN),
|
||||
DEFINE_FIELD(CCyberFranklin, m_flNextHornetAttackCheck, FIELD_TIME),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE(CCyberFranklin, CHGrunt);
|
||||
|
||||
|
||||
const char *CCyberFranklin::pAttackHitSounds[] =
|
||||
{
|
||||
"zombie/claw_strike1.wav",
|
||||
"zombie/claw_strike2.wav",
|
||||
"zombie/claw_strike3.wav",
|
||||
};
|
||||
|
||||
const char *CCyberFranklin::pAttackMissSounds[] =
|
||||
{
|
||||
"zombie/claw_miss1.wav",
|
||||
"zombie/claw_miss2.wav",
|
||||
};
|
||||
|
||||
const char *CCyberFranklin::pAttackSounds[] =
|
||||
{
|
||||
"franklin/attack1.wav",
|
||||
};
|
||||
|
||||
const char *CCyberFranklin::pDieSounds[] =
|
||||
{
|
||||
"franklin/death1.wav",
|
||||
"franklin/death2.wav",
|
||||
"franklin/death3.wav",
|
||||
};
|
||||
|
||||
const char *CCyberFranklin::pPainSounds[] =
|
||||
{
|
||||
"franklin/pain1.wav",
|
||||
"franklin/pain2.wav",
|
||||
};
|
||||
|
||||
const char *CCyberFranklin::pAlertSounds[] =
|
||||
{
|
||||
"franklin/alert1.wav",
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// CheckMeleeAttack1
|
||||
//=========================================================
|
||||
BOOL CCyberFranklin::CheckMeleeAttack1(float flDot, float flDist)
|
||||
{
|
||||
CBaseMonster *pEnemy;
|
||||
|
||||
if (m_hEnemy != NULL)
|
||||
{
|
||||
pEnemy = m_hEnemy->MyMonsterPointer();
|
||||
|
||||
if (!pEnemy)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (flDist <= 72 && flDot >= 0.7 &&
|
||||
pEnemy->Classify() != CLASS_ALIEN_BIOWEAPON &&
|
||||
pEnemy->Classify() != CLASS_PLAYER_BIOWEAPON)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// CheckRangeAttack1
|
||||
//
|
||||
// !!!LATER - we may want to load balance this. Several
|
||||
// tracelines are done, so we may not want to do this every
|
||||
// server frame. Definitely not while firing.
|
||||
//=========================================================
|
||||
BOOL CCyberFranklin :: CheckRangeAttack1 ( float flDot, float flDist )
|
||||
{
|
||||
if ( gpGlobals->time < m_flNextHornetAttackCheck )
|
||||
{
|
||||
return m_fCanHornetAttack;
|
||||
}
|
||||
|
||||
if (HasConditions(bits_COND_SEE_ENEMY) && flDist >= FRANKLIN_MELEE_DIST && flDist <= 1024 && flDot >= 0.5 && NoFriendlyFire())
|
||||
{
|
||||
TraceResult tr;
|
||||
Vector vecArmPos, vecArmDir;
|
||||
|
||||
// verify that a shot fired from the gun will hit the enemy before the world.
|
||||
// !!!LATER - we may wish to do something different for projectile weapons as opposed to instant-hit
|
||||
UTIL_MakeVectors( pev->angles );
|
||||
GetAttachment( 0, vecArmPos, vecArmDir );
|
||||
// UTIL_TraceLine( vecArmPos, vecArmPos + gpGlobals->v_forward * 256, ignore_monsters, ENT(pev), &tr);
|
||||
UTIL_TraceLine( vecArmPos, m_hEnemy->BodyTarget(vecArmPos), dont_ignore_monsters, ENT(pev), &tr);
|
||||
|
||||
if ( tr.flFraction == 1.0 || tr.pHit == m_hEnemy->edict() )
|
||||
{
|
||||
m_flNextHornetAttackCheck = gpGlobals->time + RANDOM_FLOAT( 2, 5 );
|
||||
m_fCanHornetAttack = TRUE;
|
||||
return m_fCanHornetAttack;
|
||||
}
|
||||
}
|
||||
|
||||
m_flNextHornetAttackCheck = gpGlobals->time + 0.2;// don't check for half second if this check wasn't successful
|
||||
m_fCanHornetAttack = FALSE;
|
||||
return m_fCanHornetAttack;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// DieSound
|
||||
//=========================================================
|
||||
void CCyberFranklin::DeathSound(void)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pDieSounds), 1.0, ATTN_NORM);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// AlertSound
|
||||
//=========================================================
|
||||
void CCyberFranklin::AlertSound(void)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pAlertSounds), 1.0, ATTN_NORM);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// AttackSound
|
||||
//=========================================================
|
||||
void CCyberFranklin::AttackSound(void)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pAttackSounds), 1.0, ATTN_NORM);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// PainSound
|
||||
//=========================================================
|
||||
void CCyberFranklin::PainSound(void)
|
||||
{
|
||||
if (m_flNextPainTime > gpGlobals->time)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_flNextPainTime = gpGlobals->time + 0.6;
|
||||
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pPainSounds), 1.0, ATTN_NORM);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Classify - indicates this monster's place in the
|
||||
// relationship table.
|
||||
//=========================================================
|
||||
int CCyberFranklin::Classify(void)
|
||||
{
|
||||
return CLASS_ALIEN_MONSTER;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// GetGunPosition return the end of the barrel
|
||||
//=========================================================
|
||||
|
||||
Vector CCyberFranklin::GetGunPosition()
|
||||
{
|
||||
return pev->origin + Vector(0, 0, 48);
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// Shoot
|
||||
//=========================================================
|
||||
void CCyberFranklin::Shoot(void)
|
||||
{
|
||||
// m_vecEnemyLKP should be center of enemy body
|
||||
Vector vecArmPos, vecArmDir;
|
||||
Vector vecDirToEnemy;
|
||||
Vector angDir;
|
||||
|
||||
if (HasConditions( bits_COND_SEE_ENEMY))
|
||||
{
|
||||
vecDirToEnemy = ( ( m_vecEnemyLKP ) - pev->origin );
|
||||
angDir = UTIL_VecToAngles( vecDirToEnemy );
|
||||
vecDirToEnemy = vecDirToEnemy.Normalize();
|
||||
}
|
||||
else
|
||||
{
|
||||
angDir = pev->angles;
|
||||
UTIL_MakeAimVectors( angDir );
|
||||
vecDirToEnemy = gpGlobals->v_forward;
|
||||
}
|
||||
|
||||
pev->effects = EF_MUZZLEFLASH;
|
||||
|
||||
// make angles +-180
|
||||
if (angDir.x > 180)
|
||||
{
|
||||
angDir.x = angDir.x - 360;
|
||||
}
|
||||
|
||||
SetBlending( 0, angDir.x );
|
||||
GetAttachment( 0, vecArmPos, vecArmDir );
|
||||
|
||||
vecArmPos = vecArmPos + vecDirToEnemy * 32;
|
||||
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecArmPos );
|
||||
WRITE_BYTE( TE_SPRITE );
|
||||
WRITE_COORD( vecArmPos.x ); // pos
|
||||
WRITE_COORD( vecArmPos.y );
|
||||
WRITE_COORD( vecArmPos.z );
|
||||
WRITE_SHORT( iFranklinMuzzleFlash ); // model
|
||||
WRITE_BYTE( 6 ); // size * 10
|
||||
WRITE_BYTE( 128 ); // brightness
|
||||
MESSAGE_END();
|
||||
|
||||
CBaseEntity *pHornet = CBaseEntity::Create( "hornet", vecArmPos, UTIL_VecToAngles( vecDirToEnemy ), edict() );
|
||||
UTIL_MakeVectors ( pHornet->pev->angles );
|
||||
pHornet->pev->velocity = gpGlobals->v_forward * 300;
|
||||
|
||||
switch ( RANDOM_LONG ( 0 , 2 ) )
|
||||
{
|
||||
case 0: EMIT_SOUND_DYN ( ENT(pev), CHAN_WEAPON, "agrunt/ag_fire1.wav", 1.0, ATTN_NORM, 0, 100 ); break;
|
||||
case 1: EMIT_SOUND_DYN ( ENT(pev), CHAN_WEAPON, "agrunt/ag_fire2.wav", 1.0, ATTN_NORM, 0, 100 ); break;
|
||||
case 2: EMIT_SOUND_DYN ( ENT(pev), CHAN_WEAPON, "agrunt/ag_fire3.wav", 1.0, ATTN_NORM, 0, 100 ); break;
|
||||
}
|
||||
|
||||
CBaseMonster *pHornetMonster = pHornet->MyMonsterPointer();
|
||||
|
||||
if ( pHornetMonster )
|
||||
{
|
||||
pHornetMonster->m_hEnemy = m_hEnemy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// HandleAnimEvent - catches the monster-specific messages
|
||||
// that occur when tagged animation frames are played.
|
||||
//=========================================================
|
||||
void CCyberFranklin::HandleAnimEvent(MonsterEvent_t *pEvent)
|
||||
{
|
||||
switch( pEvent->event )
|
||||
{
|
||||
case HGRUNT_AE_DROP_GUN:
|
||||
case HGRUNT_AE_RELOAD:
|
||||
case HGRUNT_AE_GREN_TOSS:
|
||||
case HGRUNT_AE_GREN_LAUNCH:
|
||||
case HGRUNT_AE_GREN_DROP:
|
||||
break;
|
||||
|
||||
case HGRUNT_AE_BURST1:
|
||||
case HGRUNT_AE_BURST2:
|
||||
case HGRUNT_AE_BURST3:
|
||||
Shoot();
|
||||
break;
|
||||
|
||||
case HGRUNT_AE_KICK:
|
||||
{
|
||||
CBaseEntity *pHurt = Kick();
|
||||
|
||||
if ( pHurt )
|
||||
{
|
||||
// SOUND HERE!
|
||||
UTIL_MakeVectors( pev->angles );
|
||||
|
||||
if (pHurt->pev->flags & (FL_MONSTER | FL_CLIENT))
|
||||
{
|
||||
pHurt->pev->punchangle.x = 15;
|
||||
}
|
||||
|
||||
pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_forward * 100 + gpGlobals->v_up * 50;
|
||||
pHurt->TakeDamage( pev, pev, gSkillData.hgruntDmgKick, DMG_CLUB );
|
||||
|
||||
// Play a random attack hit sound
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY( pAttackHitSounds ), 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5, 5));
|
||||
}
|
||||
else// Play a random attack miss sound
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, RANDOM_SOUND_ARRAY( pAttackMissSounds ), 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG(-5, 5));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
CHGrunt::HandleAnimEvent( pEvent );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CCyberFranklin::Spawn()
|
||||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL(ENT(pev), "models/franklin2.mdl");
|
||||
UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX);
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->effects = 0;
|
||||
pev->health = gSkillData.cyberfranklinHealth;
|
||||
m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
m_flNextGrenadeCheck = gpGlobals->time + 1;
|
||||
m_flNextPainTime = gpGlobals->time;
|
||||
m_iSentence = -1;
|
||||
|
||||
m_afCapability = bits_CAP_SQUAD | bits_CAP_TURN_HEAD | bits_CAP_DOORS_GROUP;
|
||||
|
||||
m_fEnemyEluded = FALSE;
|
||||
m_fFirstEncounter = TRUE;// this is true when the grunt spawns, because he hasn't encountered an enemy yet.
|
||||
|
||||
m_HackedGunPos = Vector(24, 64, 48);
|
||||
|
||||
pev->weapons = HGRUNT_9MMAR;
|
||||
|
||||
m_cClipSize = HORNETGUN_MAX_CLIP;
|
||||
|
||||
m_cAmmoLoaded = m_cClipSize;
|
||||
|
||||
pev->body = 0;
|
||||
pev->skin = 0;
|
||||
|
||||
CTalkMonster::g_talkWaitTime = 0;
|
||||
|
||||
MonsterInit();
|
||||
|
||||
m_afCapability &= ~bits_CAP_RANGE_ATTACK2;
|
||||
|
||||
ClearConditions(bits_COND_NO_AMMO_LOADED);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CCyberFranklin::Precache()
|
||||
{
|
||||
PRECACHE_MODEL("models/franklin2.mdl");
|
||||
|
||||
PRECACHE_SOUND_ARRAY(pAttackHitSounds);
|
||||
PRECACHE_SOUND_ARRAY(pAttackMissSounds);
|
||||
PRECACHE_SOUND_ARRAY(pDieSounds);
|
||||
PRECACHE_SOUND_ARRAY(pPainSounds);
|
||||
PRECACHE_SOUND_ARRAY(pAttackSounds);
|
||||
PRECACHE_SOUND_ARRAY(pAlertSounds);
|
||||
|
||||
PRECACHE_SOUND("franklin/franklin_step.wav");
|
||||
|
||||
PRECACHE_SOUND("hassault/hw_shoot1.wav");
|
||||
|
||||
iFranklinMuzzleFlash = PRECACHE_MODEL("sprites/muz4.spr");
|
||||
|
||||
UTIL_PrecacheOther("hornet");
|
||||
|
||||
m_voicePitch = 100;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========================================================
|
||||
// SetActivity
|
||||
//=========================================================
|
||||
void CCyberFranklin::SetActivity(Activity NewActivity)
|
||||
{
|
||||
int iSequence = ACTIVITY_NOT_AVAILABLE;
|
||||
void *pmodel = GET_MODEL_PTR(ENT(pev));
|
||||
|
||||
switch (NewActivity)
|
||||
{
|
||||
case ACT_RANGE_ATTACK1:
|
||||
{
|
||||
// get crouching shoot
|
||||
iSequence = LookupSequence("crouching_mp5");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CHGrunt::SetActivity(NewActivity);
|
||||
return;
|
||||
}
|
||||
|
||||
m_Activity = NewActivity; // Go ahead and set this so it doesn't keep trying when the anim is not present
|
||||
|
||||
// Set to the desired anim, or default anim if the desired is not present
|
||||
if (iSequence > ACTIVITY_NOT_AVAILABLE)
|
||||
{
|
||||
if (pev->sequence != iSequence || !m_fSequenceLoops)
|
||||
{
|
||||
pev->frame = 0;
|
||||
}
|
||||
|
||||
pev->sequence = iSequence; // Set to the reset anim (if it's there)
|
||||
ResetSequenceInfo();
|
||||
SetYawSpeed();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not available try to get default anim
|
||||
ALERT(at_console, "%s has no sequence for act:%d\n", STRING(pev->classname), NewActivity);
|
||||
pev->sequence = 0; // Set to the reset anim (if it's there)
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// start task
|
||||
//=========================================================
|
||||
void CCyberFranklin::StartTask(Task_t *pTask)
|
||||
{
|
||||
m_iTaskStatus = TASKSTATUS_RUNNING;
|
||||
|
||||
switch (pTask->iTask)
|
||||
{
|
||||
case TASK_MELEE_ATTACK1:
|
||||
AttackSound();
|
||||
CHGrunt::StartTask(pTask);
|
||||
break;
|
||||
|
||||
default:
|
||||
CHGrunt::StartTask(pTask);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/***
|
||||
*
|
||||
* 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 "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "schedule.h"
|
||||
#include "nodes.h"
|
||||
#include "effects.h"
|
||||
#include "decals.h"
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#include "flame.h"
|
||||
#include "weapons.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS(flame, CFlame);
|
||||
|
||||
TYPEDESCRIPTION CFlame::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD(CFlame, m_maxFrame, FIELD_INTEGER),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE(CFlame, CBaseEntity);
|
||||
|
||||
void CFlame::Spawn(void)
|
||||
{
|
||||
pev->movetype = MOVETYPE_FLY;
|
||||
|
||||
pev->solid = SOLID_BBOX;
|
||||
pev->rendermode = kRenderTransAlpha;
|
||||
pev->renderamt = 255;
|
||||
pev->effects = EF_DIMLIGHT;
|
||||
|
||||
SET_MODEL(ENT(pev), "sprites/fthrow.spr");
|
||||
pev->frame = 0;
|
||||
pev->scale = RANDOM_FLOAT(0.9f, 1.1f);
|
||||
pev->dmg = gSkillData.plrDmgFlame;
|
||||
|
||||
UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0));
|
||||
|
||||
m_maxFrame = (float)MODEL_FRAMES(pev->modelindex) - 1;
|
||||
}
|
||||
|
||||
void CFlame::Animate(void)
|
||||
{
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
|
||||
pev->frame += 2;
|
||||
|
||||
if (pev->frame)
|
||||
{
|
||||
if (pev->frame > m_maxFrame)
|
||||
{
|
||||
pev->frame = m_maxFrame;
|
||||
|
||||
SetThink(&CFlame::SUB_Remove);
|
||||
pev->nextthink = gpGlobals->time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFlame::Shoot(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity)
|
||||
{
|
||||
CFlame *pFlame = GetClassPtr((CFlame *)NULL);
|
||||
pFlame->Spawn();
|
||||
|
||||
UTIL_SetOrigin(pFlame->pev, vecStart);
|
||||
pFlame->pev->velocity = vecVelocity;
|
||||
pFlame->pev->owner = ENT(pevOwner);
|
||||
pFlame->pev->flags |= EF_BRIGHTLIGHT; // Required to make flame glow.
|
||||
|
||||
pFlame->SetThink(&CFlame::Animate);
|
||||
pFlame->pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
||||
void CFlame::Touch(CBaseEntity *pOther)
|
||||
{
|
||||
if (pOther->pev->takedamage)
|
||||
{
|
||||
pOther->TakeDamage(pev, pev, pev->dmg, DMG_BURN | DMG_NEVERGIB);
|
||||
SpawnBlood(pev->origin, pOther->BloodColor(), pev->dmg);
|
||||
}
|
||||
|
||||
SetThink(&CFlame::SUB_Remove);
|
||||
pev->nextthink = gpGlobals->time;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/***
|
||||
*
|
||||
* 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 FLAME_H
|
||||
#define FLAME_H
|
||||
|
||||
//=========================================================
|
||||
// Flamethrower flame entity
|
||||
//=========================================================
|
||||
class CFlame : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
|
||||
static void Shoot(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity);
|
||||
void Touch(CBaseEntity *pOther);
|
||||
void EXPORT Animate(void);
|
||||
|
||||
virtual int Save(CSave &save);
|
||||
virtual int Restore(CRestore &restore);
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
int m_maxFrame;
|
||||
};
|
||||
|
||||
#endif // FLAME_H
|
|
@ -0,0 +1,137 @@
|
|||
/***
|
||||
*
|
||||
* 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 "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "schedule.h"
|
||||
#include "game.h"
|
||||
#include "headcrab.h"
|
||||
|
||||
class CHand : public CHeadCrab
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
void StartTask(Task_t *pTask);
|
||||
void EXPORT LeapTouch(CBaseEntity *pOther);
|
||||
|
||||
void PainSound(void) { }
|
||||
void DeathSound(void) { }
|
||||
void IdleSound(void) { }
|
||||
void AlertSound(void) { }
|
||||
void AttackSound(void) { }
|
||||
|
||||
static const char *pAttackSounds[];
|
||||
static const char *pBiteSounds[];
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(einar_hand, CHand);
|
||||
|
||||
const char *CHand::pAttackSounds[] =
|
||||
{
|
||||
"thehand/hnd_attack1.wav",
|
||||
};
|
||||
|
||||
const char *CHand::pBiteSounds[] =
|
||||
{
|
||||
"thehand/hnd_headbite.wav",
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CHand::Spawn()
|
||||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL(ENT(pev), "models/thehand.mdl");
|
||||
UTIL_SetSize(pev, Vector(-12, -12, 0), Vector(12, 12, 24));
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->effects = 0;
|
||||
pev->health = gSkillData.headcrabHealth;
|
||||
pev->view_ofs = Vector(0, 0, 20);// position of the eyes relative to monster's origin.
|
||||
pev->yaw_speed = 5;//!!! should we put this in the monster's changeanim function since turn rates may vary with state/anim?
|
||||
m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
|
||||
MonsterInit();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CHand::Precache()
|
||||
{
|
||||
PRECACHE_MODEL("models/thehand.mdl");
|
||||
|
||||
PRECACHE_SOUND_ARRAY(pAttackSounds);
|
||||
PRECACHE_SOUND_ARRAY(pBiteSounds);
|
||||
|
||||
PRECACHE_SOUND("headcrab/hc_attack1.wav");
|
||||
PRECACHE_SOUND("headcrab/hc_attack2.wav");
|
||||
PRECACHE_SOUND("headcrab/hc_attack3.wav");
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// LeapTouch - this is the hand's touch function when it
|
||||
// is in the air
|
||||
//=========================================================
|
||||
void CHand::LeapTouch(CBaseEntity *pOther)
|
||||
{
|
||||
if (!pOther->pev->takedamage)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pOther->Classify() == Classify())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't hit if back on ground
|
||||
if (!FBitSet(pev->flags, FL_ONGROUND))
|
||||
{
|
||||
EMIT_SOUND_DYN(edict(), CHAN_WEAPON, RANDOM_SOUND_ARRAY(pBiteSounds), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch());
|
||||
|
||||
pOther->TakeDamage(pev, pev, GetDamageAmount(), DMG_SLASH);
|
||||
}
|
||||
|
||||
SetTouch(NULL);
|
||||
}
|
||||
|
||||
void CHand::StartTask(Task_t *pTask)
|
||||
{
|
||||
m_iTaskStatus = TASKSTATUS_RUNNING;
|
||||
|
||||
switch (pTask->iTask)
|
||||
{
|
||||
case TASK_RANGE_ATTACK1:
|
||||
{
|
||||
EMIT_SOUND_DYN(edict(), CHAN_WEAPON, pAttackSounds[0], GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch());
|
||||
m_IdealActivity = ACT_RANGE_ATTACK1;
|
||||
SetTouch(&CHand::LeapTouch);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
CHeadCrab::StartTask(pTask);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/***
|
||||
*
|
||||
* 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 hkg36_e {
|
||||
HKG36_IDLE = 0,
|
||||
HKG36_RELOAD,
|
||||
HKG36_DRAW,
|
||||
HKG36_SHOOT1,
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_th_sniper, CHKG36);
|
||||
|
||||
int CHKG36::GetPrimaryAttackActivity(void)
|
||||
{
|
||||
return HKG36_SHOOT1;
|
||||
}
|
||||
|
||||
int CHKG36::GetZoomedAttackActivity(void)
|
||||
{
|
||||
return HKG36_SHOOT1;
|
||||
}
|
||||
|
||||
int CHKG36::GetItemInfo(ItemInfo *p)
|
||||
{
|
||||
p->pszName = STRING(pev->classname);
|
||||
p->pszAmmo1 = "sniper";
|
||||
p->iMaxAmmo1 = SNIPER_MAX_CARRY;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = SNIPER_MAX_CLIP;
|
||||
p->iFlags = 0;
|
||||
p->iSlot = 2;
|
||||
p->iPosition = 3;
|
||||
p->iId = m_iId = WEAPON_HKG36;
|
||||
p->iWeight = SNIPER_WEIGHT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CHKG36::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_HKG36;
|
||||
SET_MODEL(ENT(pev), "models/w_hkg36.mdl");
|
||||
|
||||
m_iDefaultAmmo = SNIPER_DEFAULT_GIVE;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
|
||||
void CHKG36::Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/v_hkg36.mdl");
|
||||
PRECACHE_MODEL("models/w_hkg36.mdl");
|
||||
PRECACHE_MODEL("models/p_hkg36.mdl");
|
||||
|
||||
PRECACHE_MODEL("models/w_antidote.mdl");
|
||||
PRECACHE_SOUND("items/9mmclip1.wav");
|
||||
|
||||
PRECACHE_SOUND("weapons/sniper.wav");
|
||||
PRECACHE_SOUND("weapons/ap9_bolt.wav");
|
||||
PRECACHE_SOUND("weapons/ap9_clipin.wav");
|
||||
PRECACHE_SOUND("weapons/ap9_clipout.wav");
|
||||
|
||||
PRECACHE_SOUND("weapons/357_cock1.wav");
|
||||
|
||||
m_usFireSniper = PRECACHE_EVENT(1, "events/sniper.sc");
|
||||
}
|
||||
|
||||
BOOL CHKG36::Deploy()
|
||||
{
|
||||
BOOL bResult = DefaultDeploy("models/v_hkg36.mdl", "models/p_hkg36.mdl", HKG36_DRAW, "hkg36", UseDecrement());
|
||||
|
||||
if ( bResult )
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1.0;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
void CHKG36::Reload(void)
|
||||
{
|
||||
if (m_pPlayer->ammo_sniper <= 0)
|
||||
return;
|
||||
|
||||
int iResult = DefaultReload(SNIPER_MAX_CLIP, HKG36_RELOAD, 3.8);
|
||||
|
||||
if (iResult)
|
||||
{
|
||||
CSniper::Reload();
|
||||
}
|
||||
}
|
||||
|
||||
void CHKG36::WeaponIdle(void)
|
||||
{
|
||||
CSniper::WeaponIdle();
|
||||
|
||||
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
|
||||
return;
|
||||
|
||||
m_flTimeWeaponIdle = 17.0 / 30.0;
|
||||
|
||||
SendWeaponAnim(HKG36_IDLE, UseDecrement());
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/***
|
||||
*
|
||||
* 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"
|
||||
|
||||
enum medkit_e {
|
||||
MEDKIT_IDLE = 0,
|
||||
MEDKIT_LONGIDLE,
|
||||
MEDKIT_LONGUSE,
|
||||
MEDKIT_SHORTUSE,
|
||||
MEDKIT_HOLSTER,
|
||||
MEDKIT_DRAW,
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_th_medkit, CMedkit);
|
||||
|
||||
void CMedkit::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_MEDKIT;
|
||||
SET_MODEL(ENT(pev), "models/w_tfc_medkit.mdl");
|
||||
|
||||
m_iDefaultAmmo = MEDKIT_DEFAULT_GIVE;
|
||||
|
||||
m_flSoundDelay = 0;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
|
||||
void CMedkit::Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/v_tfc_medkit.mdl");
|
||||
PRECACHE_MODEL("models/w_tfc_medkit.mdl");
|
||||
PRECACHE_MODEL("models/p_tfc_medkit.mdl");
|
||||
|
||||
PRECACHE_SOUND("items/9mmclip1.wav");
|
||||
|
||||
PRECACHE_SOUND("items/medshot4.wav");
|
||||
PRECACHE_SOUND("items/medshotno1.wav");
|
||||
|
||||
m_usMedkit = PRECACHE_EVENT(1, "events/medkit.sc");
|
||||
}
|
||||
|
||||
int CMedkit::GetItemInfo(ItemInfo *p)
|
||||
{
|
||||
p->pszName = STRING(pev->classname);
|
||||
p->pszAmmo1 = "Hornets";
|
||||
p->iMaxAmmo1 = MEDKIT_MAX_CARRY;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = WEAPON_NOCLIP;
|
||||
p->iSlot = 4;
|
||||
p->iPosition = 4;
|
||||
p->iId = m_iId = WEAPON_MEDKIT;
|
||||
p->iWeight = MEDKIT_WEIGHT;
|
||||
p->iFlags = ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CMedkit::Deploy()
|
||||
{
|
||||
m_flSoundDelay = 0;
|
||||
|
||||
return DefaultDeploy("models/v_tfc_medkit.mdl", "models/p_tfc_medkit.mdl", MEDKIT_DRAW, "medkit");
|
||||
}
|
||||
|
||||
void CMedkit::Holster(int skiplocal /*= 0*/)
|
||||
{
|
||||
m_flSoundDelay = 0;
|
||||
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
SendWeaponAnim(MEDKIT_HOLSTER);
|
||||
}
|
||||
|
||||
void CMedkit::PrimaryAttack(void)
|
||||
{
|
||||
if (m_pPlayer->pev->health >= m_pPlayer->pev->max_health)
|
||||
return;
|
||||
|
||||
if (m_pPlayer->ammo_hornets <= 0)
|
||||
{
|
||||
PlayEmptySound();
|
||||
m_flNextPrimaryAttack = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
PLAYBACK_EVENT(0, m_pPlayer->edict(), m_usMedkit);
|
||||
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(2.4);
|
||||
|
||||
if (m_flNextPrimaryAttack < UTIL_WeaponTimeBase())
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 2.4;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15);
|
||||
|
||||
m_flSoundDelay = gpGlobals->time + (38.0 / 30.0);
|
||||
}
|
||||
|
||||
void CMedkit::WeaponIdle(void)
|
||||
{
|
||||
ResetEmptySound();
|
||||
|
||||
m_pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES);
|
||||
|
||||
if (m_flSoundDelay != 0 && m_flSoundDelay <= gpGlobals->time)
|
||||
{
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
|
||||
if ( m_pPlayer->TakeHealth(gSkillData.medkitHeal, DMG_GENERIC) )
|
||||
{
|
||||
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--;
|
||||
}
|
||||
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "items/medshot4.wav", 1.0, ATTN_NORM, 0, RANDOM_LONG(90, 100));
|
||||
|
||||
m_flSoundDelay = 0;
|
||||
}
|
||||
|
||||
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
|
||||
return;
|
||||
|
||||
int iAnim;
|
||||
float flRand = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 0.0, 1.0);
|
||||
|
||||
if (flRand <= 0.75)
|
||||
{
|
||||
iAnim = MEDKIT_LONGIDLE;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 72.0 / 30.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = MEDKIT_IDLE;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 36.0 / 30.0;
|
||||
}
|
||||
|
||||
SendWeaponAnim(iAnim, 1);
|
||||
}
|
||||
|
||||
BOOL CMedkit::PlayEmptySound(void)
|
||||
{
|
||||
if (m_iPlayEmptySound)
|
||||
{
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "items/medshotno1.wav", 0.8, ATTN_NORM);
|
||||
m_iPlayEmptySound = 0;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
/***
|
||||
*
|
||||
* 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 "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "schedule.h"
|
||||
#include "nodes.h"
|
||||
#include "effects.h"
|
||||
#include "decals.h"
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#include "bullsquid.h"
|
||||
|
||||
extern int iSquidSpitSprite;
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
//=========================================================
|
||||
#define MSQUID_AE_SPIT ( 1 )
|
||||
#define MSQUID_AE_BITE ( 2 )
|
||||
#define MSQUID_AE_BLINK ( 3 )
|
||||
#define MSQUID_AE_TAILWHIP ( 4 )
|
||||
#define MSQUID_AE_HOP ( 5 )
|
||||
#define MSQUID_AE_THROW ( 6 )
|
||||
|
||||
class CMegasquid : public CBullsquid
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
void HandleAnimEvent(MonsterEvent_t *pEvent);
|
||||
|
||||
BOOL CheckMeleeAttack1(float flDot, float flDist) { return FALSE; }
|
||||
BOOL CheckMeleeAttack2(float flDot, float flDist);
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(monster_th_megasquid, CMegasquid);
|
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CMegasquid::Spawn()
|
||||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL(ENT(pev), "models/megasquid.mdl");
|
||||
UTIL_SetSize(pev, Vector(-160, -160, 0), Vector(160, 160, 256));
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->effects = 0;
|
||||
pev->health = gSkillData.megasquidHealth;
|
||||
m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
|
||||
m_fCanThreatDisplay = FALSE;
|
||||
m_flNextSpitTime = gpGlobals->time;
|
||||
|
||||
pev->view_ofs = Vector(0, 0, 128);
|
||||
|
||||
MonsterInit();
|
||||
|
||||
// Remove tail whip attack.
|
||||
m_afCapability &= ~bits_CAP_MELEE_ATTACK1;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CMegasquid::Precache()
|
||||
{
|
||||
CBullsquid::Precache();
|
||||
|
||||
PRECACHE_MODEL("models/megasquid.mdl");
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// CheckMeleeAttack2 - bullsquid is a big guy, so has a longer
|
||||
// melee range than most monsters. This is the bite attack.
|
||||
// this attack will not be performed if the tailwhip attack
|
||||
// is valid.
|
||||
//=========================================================
|
||||
BOOL CMegasquid::CheckMeleeAttack2(float flDot, float flDist)
|
||||
{
|
||||
if (flDist <= 200 && flDot >= 0.7) // The player & bullsquid can be as much as their bboxes
|
||||
{ // apart (48 * sqrt(3)) and he can still attack (85 is a little more than 48*sqrt(3))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// HandleAnimEvent - catches the monster-specific messages
|
||||
// that occur when tagged animation frames are played.
|
||||
//=========================================================
|
||||
void CMegasquid::HandleAnimEvent(MonsterEvent_t *pEvent)
|
||||
{
|
||||
switch (pEvent->event)
|
||||
{
|
||||
case MSQUID_AE_SPIT:
|
||||
{
|
||||
Vector vecSpitOffset;
|
||||
Vector vecSpitDir;
|
||||
|
||||
UTIL_MakeVectors ( pev->angles );
|
||||
|
||||
// !!!HACKHACK - the spot at which the spit originates (in front of the mouth) was measured in 3ds and hardcoded here.
|
||||
// we should be able to read the position of bones at runtime for this info.
|
||||
vecSpitOffset = ( gpGlobals->v_right * 40 + gpGlobals->v_forward * 185 + gpGlobals->v_up * 115 ); // 8 37 23
|
||||
vecSpitOffset = ( pev->origin + vecSpitOffset );
|
||||
vecSpitDir = ( ( m_hEnemy->pev->origin + m_hEnemy->pev->view_ofs ) - vecSpitOffset ).Normalize();
|
||||
|
||||
vecSpitDir.x += RANDOM_FLOAT( -0.05, 0.05 );
|
||||
vecSpitDir.y += RANDOM_FLOAT( -0.05, 0.05 );
|
||||
vecSpitDir.z += RANDOM_FLOAT( -0.05, 0 );
|
||||
|
||||
|
||||
// do stuff for this event.
|
||||
AttackSound();
|
||||
|
||||
// spew the spittle temporary ents.
|
||||
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpitOffset );
|
||||
WRITE_BYTE( TE_SPRITE_SPRAY );
|
||||
WRITE_COORD( vecSpitOffset.x); // pos
|
||||
WRITE_COORD( vecSpitOffset.y);
|
||||
WRITE_COORD( vecSpitOffset.z);
|
||||
WRITE_COORD( vecSpitDir.x); // dir
|
||||
WRITE_COORD( vecSpitDir.y);
|
||||
WRITE_COORD( vecSpitDir.z);
|
||||
WRITE_SHORT( iSquidSpitSprite ); // model
|
||||
WRITE_BYTE ( 15 ); // count
|
||||
WRITE_BYTE ( 210 ); // speed
|
||||
WRITE_BYTE ( 25 ); // noise ( client will divide by 100 )
|
||||
MESSAGE_END();
|
||||
|
||||
CSquidSpit::Shoot( pev, vecSpitOffset, vecSpitDir * 900 );
|
||||
}
|
||||
break;
|
||||
|
||||
case MSQUID_AE_BITE:
|
||||
{
|
||||
// SOUND HERE!
|
||||
CBaseEntity *pHurt = CheckTraceHullAttack(220, gSkillData.bullsquidDmgBite, DMG_SLASH);
|
||||
|
||||
if (pHurt)
|
||||
{
|
||||
//pHurt->pev->punchangle.z = -15;
|
||||
//pHurt->pev->punchangle.x = -45;
|
||||
pHurt->pev->velocity = pHurt->pev->velocity - gpGlobals->v_forward * 100;
|
||||
pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_up * 100;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSQUID_AE_THROW:
|
||||
{
|
||||
int iPitch;
|
||||
|
||||
// squid throws its prey IF the prey is a client.
|
||||
CBaseEntity *pHurt = CheckTraceHullAttack(220, 0, 0);
|
||||
|
||||
|
||||
if (pHurt)
|
||||
{
|
||||
// croonchy bite sound
|
||||
iPitch = RANDOM_FLOAT(90, 110);
|
||||
switch (RANDOM_LONG(0, 1))
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "bullchicken/bc_bite2.wav", 1, ATTN_NORM, 0, iPitch);
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "bullchicken/bc_bite3.wav", 1, ATTN_NORM, 0, iPitch);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//pHurt->pev->punchangle.x = RANDOM_LONG(0,34) - 5;
|
||||
//pHurt->pev->punchangle.z = RANDOM_LONG(0,49) - 25;
|
||||
//pHurt->pev->punchangle.y = RANDOM_LONG(0,89) - 45;
|
||||
|
||||
// screeshake transforms the viewmodel as well as the viewangle. No problems with seeing the ends of the viewmodels.
|
||||
UTIL_ScreenShake(pHurt->pev->origin, 25.0, 1.5, 0.7, 2);
|
||||
|
||||
if (pHurt->IsPlayer())
|
||||
{
|
||||
UTIL_MakeVectors(pev->angles);
|
||||
pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_forward * 300 + gpGlobals->v_up * 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
CBullsquid::HandleAnimEvent(pEvent);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,284 @@
|
|||
/***
|
||||
*
|
||||
* 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"
|
||||
|
||||
#define SHOVEL_BODYHIT_VOLUME 128
|
||||
#define SHOVEL_WALLHIT_VOLUME 512
|
||||
|
||||
void FindHullIntersection(const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity);
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_th_shovel, CShovel);
|
||||
|
||||
enum shovel_e {
|
||||
SHOVEL_IDLE = 0,
|
||||
SHOVEL_DRAW,
|
||||
SHOVEL_HOLSTER,
|
||||
SHOVEL_ATTACK1HIT,
|
||||
SHOVEL_ATTACK1MISS,
|
||||
SHOVEL_ATTACK2MISS,
|
||||
SHOVEL_ATTACK2HIT,
|
||||
SHOVEL_ATTACK3MISS,
|
||||
SHOVEL_ATTACK3HIT,
|
||||
SHOVEL_IDLE2,
|
||||
SHOVEL_IDLE3,
|
||||
};
|
||||
|
||||
|
||||
void CShovel::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_SHOVEL;
|
||||
SET_MODEL(ENT(pev), "models/w_shovel.mdl");
|
||||
m_iClip = -1;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
|
||||
void CShovel::Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/v_shovel.mdl");
|
||||
PRECACHE_MODEL("models/w_shovel.mdl");
|
||||
PRECACHE_MODEL("models/p_shovel.mdl");
|
||||
PRECACHE_SOUND("weapons/cbar_hit1.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_hit2.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_hitbod1.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_hitbod2.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_hitbod3.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_miss1.wav");
|
||||
|
||||
PRECACHE_SOUND("kelly/cbar_hitkelly1.wav");
|
||||
PRECACHE_SOUND("kelly/cbar_hitkelly2.wav");
|
||||
PRECACHE_SOUND("kelly/cbar_hitkelly3.wav");
|
||||
|
||||
m_usShovel = PRECACHE_EVENT(1, "events/shovel.sc");
|
||||
}
|
||||
|
||||
int CShovel::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_SHOVEL;
|
||||
p->iWeight = SHOVEL_WEIGHT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL CShovel::Deploy()
|
||||
{
|
||||
return DefaultDeploy("models/v_shovel.mdl", "models/p_shovel.mdl", SHOVEL_DRAW, "shovel");
|
||||
}
|
||||
|
||||
void CShovel::Holster(int skiplocal /* = 0 */)
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
SendWeaponAnim(SHOVEL_HOLSTER);
|
||||
}
|
||||
|
||||
void CShovel::PrimaryAttack()
|
||||
{
|
||||
if (!Swing(1))
|
||||
{
|
||||
SetThink(&CShovel::SwingAgain);
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
int CShovel::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_usShovel,
|
||||
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.56); // 0.5
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// switch (((m_iSwing++) % 2) + 1)
|
||||
switch (RANDOM_LONG(0, 2))
|
||||
{
|
||||
case 0:
|
||||
SendWeaponAnim(SHOVEL_ATTACK1MISS); break;
|
||||
case 1:
|
||||
SendWeaponAnim(SHOVEL_ATTACK2MISS); break;
|
||||
case 2:
|
||||
SendWeaponAnim(SHOVEL_ATTACK3MISS); 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.plrDmgShovel, gpGlobals->v_forward, &tr, DMG_CLUB);
|
||||
}
|
||||
else
|
||||
{
|
||||
// subsequent swings do half
|
||||
pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgShovel / 2, 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)
|
||||
{
|
||||
// Skeletons make different hit sounds.
|
||||
if (pEntity->Classify() == CLASS_SKELETON)
|
||||
{
|
||||
// play thwack or smack sound
|
||||
switch (RANDOM_LONG(0, 2))
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "kelly/cbar_hitkelly1.wav", 1, ATTN_NORM); break;
|
||||
case 1:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "kelly/cbar_hitkelly2.wav", 1, ATTN_NORM); break;
|
||||
case 2:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "kelly/cbar_hitkelly3.wav", 1, ATTN_NORM); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// play thwack or smack sound
|
||||
switch (RANDOM_LONG(0, 2))
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM); break;
|
||||
case 1:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM); break;
|
||||
case 2:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = SHOVEL_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, 98 + RANDOM_LONG(0, 3));
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hit2.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG(0, 3));
|
||||
break;
|
||||
}
|
||||
|
||||
// delay the decal a bit
|
||||
m_trHit = tr;
|
||||
}
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = flVol * SHOVEL_WALLHIT_VOLUME;
|
||||
#endif
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.26); // 0.25
|
||||
|
||||
SetThink(&CShovel::Smack);
|
||||
pev->nextthink = UTIL_WeaponTimeBase() + 0.2;
|
||||
|
||||
|
||||
}
|
||||
return fDidHit;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
/***
|
||||
*
|
||||
* 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"
|
||||
|
||||
extern int gmsgZoom;
|
||||
|
||||
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::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::SniperFire(float flSpread, float flCycleTime, BOOL fUseAutoAim, int iActivity)
|
||||
{
|
||||
// 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;
|
||||
|
||||
if (fUseAutoAim)
|
||||
{
|
||||
vecAiming = m_pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES);
|
||||
}
|
||||
else
|
||||
{
|
||||
vecAiming = gpGlobals->v_forward;
|
||||
}
|
||||
|
||||
Vector vecDir;
|
||||
vecDir = m_pPlayer->FireBulletsPlayer(1, vecSrc, vecAiming, Vector(flSpread, flSpread, flSpread), 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, iActivity, 0, 0, 0);
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay(flCycleTime);
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay(flCycleTime);
|
||||
|
||||
if (m_flNextPrimaryAttack < UTIL_WeaponTimeBase())
|
||||
m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + flCycleTime;
|
||||
|
||||
if (m_flNextSecondaryAttack < UTIL_WeaponTimeBase())
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + flCycleTime;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15);
|
||||
}
|
||||
|
||||
void CSniper::SecondaryAttack(void)
|
||||
{
|
||||
ToggleZoom();
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay(0.5);
|
||||
}
|
||||
|
||||
void CSniper::PrimaryAttack()
|
||||
{
|
||||
BOOL fUseAutoAim;
|
||||
int iAnim;
|
||||
float flSpread;
|
||||
float flCycleTime;
|
||||
|
||||
fUseAutoAim = TRUE;
|
||||
iAnim = m_fInZoom ? GetZoomedAttackActivity() : GetPrimaryAttackActivity();
|
||||
flSpread = m_fInZoom ? 0.01 : 0.03;
|
||||
flCycleTime = m_fInZoom ? 0.7 : 0.1;
|
||||
|
||||
SniperFire(flSpread, flCycleTime, fUseAutoAim, iAnim);
|
||||
}
|
||||
|
||||
void CSniper::Reload(void)
|
||||
{
|
||||
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
|
||||
return;
|
||||
|
||||
if (m_fInZoom)
|
||||
{
|
||||
SetZoomState(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void CSniper::WeaponIdle(void)
|
||||
{
|
||||
ResetEmptySound();
|
||||
|
||||
m_pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES);
|
||||
}
|
||||
|
||||
void CSniper::SetZoomState(BOOL bState)
|
||||
{
|
||||
m_fInZoom = bState;
|
||||
m_pPlayer->pev->fov = m_pPlayer->m_iFOV = bState ? 40 : 0; // 0 means reset to default fov
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
// Toggle Zoom HUD.
|
||||
MESSAGE_BEGIN(MSG_ONE, gmsgZoom, NULL, m_pPlayer->pev);
|
||||
WRITE_BYTE( bState );
|
||||
WRITE_BYTE( m_iId );
|
||||
MESSAGE_END();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSniper::ToggleZoom(void)
|
||||
{
|
||||
SetZoomState(!m_fInZoom);
|
||||
}
|
||||
|
||||
|
||||
class CSniperAmmo : public CBasePlayerAmmo
|
||||
{
|
||||
void Spawn(void)
|
||||
{
|
||||
Precache();
|
||||
SET_MODEL(ENT(pev), "models/w_antidote.mdl");
|
||||
CBasePlayerAmmo::Spawn();
|
||||
}
|
||||
void Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/w_antidote.mdl");
|
||||
PRECACHE_SOUND("items/9mmclip1.wav");
|
||||
}
|
||||
BOOL AddAmmo(CBaseEntity *pOther)
|
||||
{
|
||||
if (pOther->GiveAmmo(AMMO_SNIPER_GIVE, "sniper", SNIPER_MAX_CARRY) != -1)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS(ammo_th_sniper, CSniperAmmo);
|
||||
LINK_ENTITY_TO_CLASS(ammo_einar1, CSniperAmmo);
|
|
@ -0,0 +1,275 @@
|
|||
/***
|
||||
*
|
||||
* 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"
|
||||
|
||||
#define SPANNER_BODYHIT_VOLUME 128
|
||||
#define SPANNER_WALLHIT_VOLUME 512
|
||||
|
||||
void FindHullIntersection(const Vector &vecSrc, TraceResult &tr, float *mins, float *maxs, edict_t *pEntity);
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_th_spanner, CSpanner);
|
||||
|
||||
enum spanner_e {
|
||||
SPANNER_IDLE = 0,
|
||||
SPANNER_ATTACK1,
|
||||
SPANNER_ATTACK2,
|
||||
SPANNER_USE,
|
||||
SPANNER_DRAW,
|
||||
SPANNER_HOLSTER,
|
||||
};
|
||||
|
||||
void CSpanner::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_SPANNER;
|
||||
SET_MODEL(ENT(pev), "models/backpack.mdl");
|
||||
m_iClip = -1;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
|
||||
void CSpanner::Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/v_tfc_spanner.mdl");
|
||||
PRECACHE_MODEL("models/backpack.mdl");
|
||||
PRECACHE_MODEL("models/p_spanner.mdl");
|
||||
PRECACHE_SOUND("weapons/cbar_hit1.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_hit2.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_hitbod1.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_hitbod2.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_hitbod3.wav");
|
||||
PRECACHE_SOUND("weapons/cbar_miss1.wav");
|
||||
|
||||
PRECACHE_SOUND("kelly/cbar_hitkelly1.wav");
|
||||
PRECACHE_SOUND("kelly/cbar_hitkelly2.wav");
|
||||
PRECACHE_SOUND("kelly/cbar_hitkelly3.wav");
|
||||
|
||||
m_usSpanner = PRECACHE_EVENT(1, "events/spanner.sc");
|
||||
}
|
||||
|
||||
int CSpanner::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 = 2;
|
||||
p->iId = WEAPON_SPANNER;
|
||||
p->iWeight = SPANNER_WEIGHT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL CSpanner::Deploy()
|
||||
{
|
||||
return DefaultDeploy("models/v_tfc_spanner.mdl", "models/p_spanner.mdl", SPANNER_DRAW, "spanner");
|
||||
}
|
||||
|
||||
void CSpanner::Holster(int skiplocal /* = 0 */)
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
SendWeaponAnim(SPANNER_HOLSTER);
|
||||
}
|
||||
|
||||
void CSpanner::PrimaryAttack()
|
||||
{
|
||||
if (!Swing(1))
|
||||
{
|
||||
SetThink(&CSpanner::SwingAgain);
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CSpanner::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_usSpanner,
|
||||
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.38); // 0.5
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ((m_iSwing++) % 2)
|
||||
{
|
||||
case 0:
|
||||
SendWeaponAnim(SPANNER_ATTACK1); break;
|
||||
case 1:
|
||||
SendWeaponAnim(SPANNER_ATTACK2); 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.plrDmgSpanner, gpGlobals->v_forward, &tr, DMG_CLUB);
|
||||
}
|
||||
else
|
||||
{
|
||||
// subsequent swings do half
|
||||
pEntity->TraceAttack(m_pPlayer->pev, gSkillData.plrDmgSpanner / 2, 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)
|
||||
{
|
||||
// Skeletons make different hit sounds.
|
||||
if (pEntity->Classify() == CLASS_SKELETON)
|
||||
{
|
||||
// play thwack or smack sound
|
||||
switch (RANDOM_LONG(0, 2))
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "kelly/cbar_hitkelly1.wav", 1, ATTN_NORM); break;
|
||||
case 1:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "kelly/cbar_hitkelly2.wav", 1, ATTN_NORM); break;
|
||||
case 2:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "kelly/cbar_hitkelly3.wav", 1, ATTN_NORM); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// play thwack or smack sound
|
||||
switch (RANDOM_LONG(0, 2))
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM); break;
|
||||
case 1:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM); break;
|
||||
case 2:
|
||||
EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM); break;
|
||||
}
|
||||
}
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = SPANNER_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, 98 + RANDOM_LONG(0, 3));
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/cbar_hit2.wav", fvolbar, ATTN_NORM, 0, 98 + RANDOM_LONG(0, 3));
|
||||
break;
|
||||
}
|
||||
|
||||
// delay the decal a bit
|
||||
m_trHit = tr;
|
||||
}
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = flVol * SPANNER_WALLHIT_VOLUME;
|
||||
#endif
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.2); // 0.25
|
||||
|
||||
SetThink(&CSpanner::Smack);
|
||||
pev->nextthink = UTIL_WeaponTimeBase() + 0.2;
|
||||
|
||||
|
||||
}
|
||||
return fDidHit;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
/***
|
||||
*
|
||||
* 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"
|
||||
|
||||
enum taurus_e {
|
||||
TAURUS_IDLE1 = 0,
|
||||
TAURUS_IDLE2,
|
||||
TAURUS_IDLE3,
|
||||
TAURUS_SHOOT,
|
||||
TAURUS_SHOOT2,
|
||||
TAURUS_SHOOT3,
|
||||
TAURUS_SHOOT_EMPTY,
|
||||
TAURUS_RELOAD,
|
||||
TAURUS_RELOAD2,
|
||||
TAURUS_DRAW,
|
||||
TAURUS_DRAW2,
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_th_taurus, CTaurus);
|
||||
|
||||
void CTaurus::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_TAURUS;
|
||||
SET_MODEL(ENT(pev), "models/w_taurus.mdl");
|
||||
|
||||
m_iDefaultAmmo = TAURUS_DEFAULT_GIVE;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
|
||||
void CTaurus::Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/v_taurus.mdl");
|
||||
PRECACHE_MODEL("models/w_taurus.mdl");
|
||||
PRECACHE_MODEL("models/p_taurus.mdl");
|
||||
|
||||
m_iShell = PRECACHE_MODEL("models/shell.mdl");// brass shell
|
||||
|
||||
PRECACHE_SOUND("items/9mmclip1.wav");
|
||||
|
||||
PRECACHE_SOUND("weapons/tau_back.wav");
|
||||
PRECACHE_SOUND("weapons/tau_clipin.wav");
|
||||
PRECACHE_SOUND("weapons/tau_clipout.wav");
|
||||
PRECACHE_SOUND("weapons/tau_fire.wav");
|
||||
PRECACHE_SOUND("weapons/tau_release.wav");
|
||||
|
||||
m_usFireTaurus = PRECACHE_EVENT(1, "events/taurus.sc");
|
||||
}
|
||||
|
||||
int CTaurus::GetItemInfo(ItemInfo *p)
|
||||
{
|
||||
p->pszName = STRING(pev->classname);
|
||||
p->pszAmmo1 = "taurus";
|
||||
p->iMaxAmmo1 = TAURUS_MAX_CARRY;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = TAURUS_MAX_CLIP;
|
||||
p->iSlot = 1;
|
||||
p->iPosition = 3;
|
||||
p->iFlags = 0;
|
||||
p->iId = m_iId = WEAPON_TAURUS;
|
||||
p->iWeight = TAURUS_WEIGHT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL CTaurus::Deploy()
|
||||
{
|
||||
return DefaultDeploy("models/v_taurus.mdl", "models/p_taurus.mdl", TAURUS_DRAW2, "taurus", 0);
|
||||
}
|
||||
|
||||
void CTaurus::PrimaryAttack(void)
|
||||
{
|
||||
if (m_iClip <= 0)
|
||||
{
|
||||
if (m_fFireOnEmpty)
|
||||
{
|
||||
PlayEmptySound();
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.28);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_iClip--;
|
||||
|
||||
m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH;
|
||||
|
||||
int flags;
|
||||
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
flags = FEV_NOTHOST;
|
||||
#else
|
||||
flags = 0;
|
||||
#endif
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
|
||||
|
||||
// silenced
|
||||
if (pev->body == 1)
|
||||
{
|
||||
m_pPlayer->m_iWeaponVolume = QUIET_GUN_VOLUME;
|
||||
m_pPlayer->m_iWeaponFlash = DIM_GUN_FLASH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// non-silenced
|
||||
m_pPlayer->m_iWeaponVolume = NORMAL_GUN_VOLUME;
|
||||
m_pPlayer->m_iWeaponFlash = NORMAL_GUN_FLASH;
|
||||
}
|
||||
|
||||
Vector vecSrc = m_pPlayer->GetGunPosition();
|
||||
Vector vecAiming = m_pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES);
|
||||
|
||||
Vector vecDir;
|
||||
vecDir = m_pPlayer->FireBulletsPlayer(1, vecSrc, vecAiming, VECTOR_CONE_3DEGREES, 8192, BULLET_PLAYER_TAURUS, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed);
|
||||
|
||||
PLAYBACK_EVENT_FULL(flags, m_pPlayer->edict(), m_usFireTaurus, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, 0, 0);
|
||||
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.28);
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15);
|
||||
}
|
||||
|
||||
void CTaurus::Reload(void)
|
||||
{
|
||||
if (m_pPlayer->ammo_taurus <= 0)
|
||||
return;
|
||||
|
||||
int iResult = DefaultReload(TAURUS_MAX_CLIP, TAURUS_RELOAD2, 2.0);
|
||||
|
||||
if (iResult)
|
||||
{
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat(m_pPlayer->random_seed, 10, 15);
|
||||
}
|
||||
}
|
||||
|
||||
void CTaurus::WeaponIdle(void)
|
||||
{
|
||||
ResetEmptySound();
|
||||
|
||||
m_pPlayer->GetAutoaimVector(AUTOAIM_10DEGREES);
|
||||
|
||||
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
|
||||
return;
|
||||
|
||||
// only idle if the slid isn't back
|
||||
if (m_iClip != 0)
|
||||
{
|
||||
int iAnim;
|
||||
float flRand = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 0.0, 1.0);
|
||||
|
||||
if (flRand <= 0.3 + 0 * 0.75)
|
||||
{
|
||||
iAnim = TAURUS_IDLE3;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 46.0 / 18.0;
|
||||
}
|
||||
else if (flRand <= 0.6 + 0 * 0.875)
|
||||
{
|
||||
iAnim = TAURUS_IDLE1;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 46.0 / 16.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = TAURUS_IDLE2;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 46.0 / 20.0;
|
||||
}
|
||||
SendWeaponAnim(iAnim, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class CTaurusAmmo : public CBasePlayerAmmo
|
||||
{
|
||||
void Spawn(void)
|
||||
{
|
||||
Precache();
|
||||
SET_MODEL(ENT(pev), "models/w_taurusclip.mdl");
|
||||
CBasePlayerAmmo::Spawn();
|
||||
}
|
||||
void Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/w_taurusclip.mdl");
|
||||
PRECACHE_SOUND("items/9mmclip1.wav");
|
||||
}
|
||||
BOOL AddAmmo(CBaseEntity *pOther)
|
||||
{
|
||||
if (pOther->GiveAmmo(AMMO_TAURUS_GIVE, "taurus", TAURUS_MAX_CARRY) != -1)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
};
|
||||
LINK_ENTITY_TO_CLASS(ammo_th_taurus, CTaurusAmmo);
|
|
@ -0,0 +1,82 @@
|
|||
/***
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****/
|
||||
/*
|
||||
|
||||
===== generic grenade.cpp ========================================================
|
||||
|
||||
*/
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "soundent.h"
|
||||
#include "decals.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS(tnt, CTnt);
|
||||
|
||||
void CTnt::Spawn(void)
|
||||
{
|
||||
pev->movetype = MOVETYPE_BOUNCE;
|
||||
|
||||
pev->solid = SOLID_BBOX;
|
||||
|
||||
SET_MODEL(ENT(pev), "models/w_tnt.mdl");
|
||||
UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0));
|
||||
|
||||
pev->dmg = 100;
|
||||
m_fRegisteredSound = FALSE;
|
||||
}
|
||||
|
||||
CGrenade * CTnt::ShootTimed(entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time)
|
||||
{
|
||||
CTnt *pTnt = GetClassPtr((CTnt *)NULL);
|
||||
pTnt->Spawn();
|
||||
UTIL_SetOrigin(pTnt->pev, vecStart);
|
||||
pTnt->pev->velocity = vecVelocity;
|
||||
pTnt->pev->angles = UTIL_VecToAngles(pTnt->pev->velocity);
|
||||
pTnt->pev->owner = ENT(pevOwner);
|
||||
|
||||
pTnt->SetTouch(&CTnt::BounceTouch); // Bounce if touched
|
||||
|
||||
// Take one second off of the desired detonation time and set the think to PreDetonate. PreDetonate
|
||||
// will insert a DANGER sound into the world sound list and delay detonation for one second so that
|
||||
// the grenade explodes after the exact amount of time specified in the call to ShootTimed().
|
||||
|
||||
pTnt->pev->dmgtime = gpGlobals->time + time;
|
||||
pTnt->SetThink(&CTnt::TumbleThink);
|
||||
pTnt->pev->nextthink = gpGlobals->time + 0.1;
|
||||
if (time < 0.1)
|
||||
{
|
||||
pTnt->pev->nextthink = gpGlobals->time;
|
||||
pTnt->pev->velocity = Vector(0, 0, 0);
|
||||
}
|
||||
|
||||
pTnt->pev->sequence = RANDOM_LONG(3, 6);
|
||||
pTnt->pev->framerate = 1.0;
|
||||
|
||||
// Tumble through the air
|
||||
// pTnt->pev->avelocity.x = -400;
|
||||
|
||||
pTnt->pev->gravity = 0.5;
|
||||
pTnt->pev->friction = 0.8;
|
||||
|
||||
SET_MODEL(ENT(pTnt->pev), "models/w_tnt.mdl");
|
||||
pTnt->pev->dmg = 100;
|
||||
|
||||
return pTnt;
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
/***
|
||||
*
|
||||
* 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 einar1_e {
|
||||
EINAR1_IDLE = 0,
|
||||
EINAR1_AIM,
|
||||
EINAR1_FIRE,
|
||||
EINAR1_DRAW,
|
||||
EINAR1_HOLSTER,
|
||||
EINAR1_AUTOIDLE,
|
||||
EINAR1_AUTOFIRE,
|
||||
EINAR1_AUTODRAW,
|
||||
EINAR1_AUTOHOLSTER,
|
||||
};
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS(weapon_einar1, CEinar1);
|
||||
|
||||
|
||||
int CEinar1::GetPrimaryAttackActivity(void)
|
||||
{
|
||||
return EINAR1_AUTOFIRE;
|
||||
}
|
||||
|
||||
int CEinar1::GetZoomedAttackActivity(void)
|
||||
{
|
||||
return EINAR1_FIRE;
|
||||
}
|
||||
|
||||
int CEinar1::GetItemInfo(ItemInfo *p)
|
||||
{
|
||||
p->pszName = STRING(pev->classname);
|
||||
p->pszAmmo1 = "sniper";
|
||||
p->iMaxAmmo1 = SNIPER_MAX_CARRY;
|
||||
p->pszAmmo2 = NULL;
|
||||
p->iMaxAmmo2 = -1;
|
||||
p->iMaxClip = SNIPER_MAX_CLIP;
|
||||
p->iFlags = 0;
|
||||
p->iSlot = 2;
|
||||
p->iPosition = 4;
|
||||
p->iId = m_iId = WEAPON_EINAR1;
|
||||
p->iWeight = SNIPER_WEIGHT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CEinar1::Spawn()
|
||||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_EINAR1;
|
||||
SET_MODEL(ENT(pev), "models/w_isotopebox.mdl");
|
||||
|
||||
m_iDefaultAmmo = SNIPER_DEFAULT_GIVE;
|
||||
|
||||
m_fInZoom = FALSE;
|
||||
m_fInAttack = 0;
|
||||
m_fInSpecialReload = 0;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
void CEinar1::Precache(void)
|
||||
{
|
||||
PRECACHE_MODEL("models/v_tfc_sniper.mdl");
|
||||
PRECACHE_MODEL("models/w_isotopebox.mdl");
|
||||
PRECACHE_MODEL("models/p_sniper.mdl");
|
||||
|
||||
PRECACHE_MODEL("models/w_antidote.mdl");
|
||||
PRECACHE_SOUND("items/9mmclip1.wav");
|
||||
|
||||
PRECACHE_SOUND("weapons/sniper.wav");
|
||||
PRECACHE_SOUND("weapons/reload3.wav");
|
||||
|
||||
PRECACHE_SOUND("weapons/357_cock1.wav");
|
||||
|
||||
m_usFireSniper = PRECACHE_EVENT(1, "events/sniper.sc");
|
||||
}
|
||||
|
||||
BOOL CEinar1::Deploy()
|
||||
{
|
||||
return DefaultDeploy("models/v_tfc_sniper.mdl", "models/p_sniper.mdl", EINAR1_AUTODRAW, "einar1");
|
||||
}
|
||||
|
||||
void CEinar1::Holster(int skiplocal /* = 0 */)
|
||||
{
|
||||
CSniper::Holster(skiplocal);
|
||||
|
||||
m_fInZoom = FALSE;
|
||||
m_fInAttack = 0;
|
||||
m_fInSpecialReload = 0;
|
||||
|
||||
SendWeaponAnim( EINAR1_AUTOHOLSTER );
|
||||
}
|
||||
|
||||
void CEinar1::PrimaryAttack()
|
||||
{
|
||||
if (m_fInSpecialReload != 0)
|
||||
return;
|
||||
|
||||
CSniper::PrimaryAttack();
|
||||
|
||||
m_fInAttack = 1;
|
||||
m_fInSpecialReload = 0;
|
||||
}
|
||||
|
||||
void CEinar1::SecondaryAttack(void)
|
||||
{
|
||||
if (m_fInSpecialReload != 0)
|
||||
return;
|
||||
|
||||
CSniper::SecondaryAttack();
|
||||
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(1);
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 5; // idle pretty soon after shooting.
|
||||
|
||||
m_fInAttack = 1;
|
||||
m_fInSpecialReload = 0;
|
||||
}
|
||||
|
||||
void CEinar1::Reload(void)
|
||||
{
|
||||
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0 || m_iClip == SNIPER_MAX_CLIP)
|
||||
return;
|
||||
|
||||
// don't reload until recoil is done
|
||||
if (m_flNextPrimaryAttack > UTIL_WeaponTimeBase())
|
||||
return;
|
||||
|
||||
if (m_fInZoom)
|
||||
{
|
||||
SetZoomState(FALSE);
|
||||
}
|
||||
|
||||
// check to see if we're ready to reload
|
||||
if (m_fInSpecialReload == 0)
|
||||
{
|
||||
SendWeaponAnim(EINAR1_AUTOHOLSTER);
|
||||
m_fInSpecialReload = 1;
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.0; // 0.5
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.6;
|
||||
m_flNextPrimaryAttack = GetNextAttackDelay(0.6);
|
||||
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.5;
|
||||
return;
|
||||
}
|
||||
else if (m_fInSpecialReload == 1)
|
||||
{
|
||||
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
|
||||
return;
|
||||
// was waiting for gun to move to side
|
||||
m_fInSpecialReload = 2;
|
||||
|
||||
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/reload3.wav", 1, ATTN_NORM, 0, 85 + RANDOM_LONG(0, 0x1f));
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.8;
|
||||
}
|
||||
else
|
||||
{
|
||||
DefaultReload( SNIPER_MAX_CLIP, EINAR1_AUTODRAW, 0.5);
|
||||
|
||||
m_fInSpecialReload = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CEinar1::WeaponIdle(void)
|
||||
{
|
||||
CSniper::WeaponIdle();
|
||||
|
||||
if (m_fInSpecialReload == 0 && m_fInAttack == 1 && (gpGlobals->time - m_flLastFireTime) > 0.1f)
|
||||
{
|
||||
SendWeaponAnim(m_fInZoom ? EINAR1_IDLE : EINAR1_AUTOIDLE);
|
||||
m_fInAttack = 0;
|
||||
}
|
||||
|
||||
if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase())
|
||||
return;
|
||||
|
||||
if (m_iClip == 0 && m_fInSpecialReload == 0 && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else if (m_fInSpecialReload != 0)
|
||||
{
|
||||
if (m_iClip != SNIPER_MAX_CLIP && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fInSpecialReload = 0;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.5;
|
||||
}
|
||||
}
|
||||
else if (m_fInSpecialReload == 0)
|
||||
{
|
||||
int iAnim;
|
||||
|
||||
if (m_fInZoom)
|
||||
{
|
||||
iAnim = EINAR1_IDLE;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + (31.0 / 10.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = EINAR1_AUTOIDLE;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + (31.0 / 15.0);
|
||||
}
|
||||
|
||||
SendWeaponAnim(iAnim, UseDecrement());
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CEinar1::ShouldWeaponIdle(void)
|
||||
{
|
||||
return (m_iClip == 0) || (m_fInSpecialReload != 0);
|
||||
}
|
|
@ -0,0 +1,397 @@
|
|||
/***
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****/
|
||||
//=========================================================
|
||||
// bullsquid - big, spotty tentacle-mouthed meanie.
|
||||
//=========================================================
|
||||
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "schedule.h"
|
||||
#include "nodes.h"
|
||||
#include "effects.h"
|
||||
#include "decals.h"
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#include "bullsquid.h"
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
//=========================================================
|
||||
#define ZBULL_AE_SPIT ( 1 )
|
||||
#define ZBULL_AE_BITE ( 2 )
|
||||
#define ZBULL_AE_BLINK ( 3 )
|
||||
#define ZBULL_AE_TAILWHIP ( 4 )
|
||||
#define ZBULL_AE_HOP ( 5 )
|
||||
#define ZBULL_AE_THROW ( 6 )
|
||||
|
||||
class CZombieBull : public CBullsquid
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
int Classify(void);
|
||||
void HandleAnimEvent(MonsterEvent_t *pEvent);
|
||||
|
||||
void IdleSound(void);
|
||||
void PainSound(void);
|
||||
void DeathSound(void);
|
||||
void AlertSound(void);
|
||||
void AttackSound(void);
|
||||
void BiteSound(void);
|
||||
|
||||
void StartTask(Task_t *pTask);
|
||||
|
||||
BOOL CheckMeleeAttack1(float flDot, float flDist);
|
||||
BOOL CheckMeleeAttack2(float flDot, float flDist);
|
||||
BOOL CheckRangeAttack1(float flDot, float flDist) { return FALSE; }
|
||||
|
||||
Schedule_t *GetSchedule(void);
|
||||
|
||||
static const char *pAttackSounds[];
|
||||
static const char *pBiteSounds[];
|
||||
static const char *pIdleSounds[];
|
||||
static const char *pAlertSounds[];
|
||||
static const char *pPainSounds[];
|
||||
static const char *pDeathSounds[];
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(monster_th_zombiebull, CZombieBull);
|
||||
|
||||
const char *CZombieBull::pAttackSounds[] =
|
||||
{
|
||||
"bull/bu_whip1.wav",
|
||||
"bull/bu_whip2.wav",
|
||||
"bull/bu_whip3.wav",
|
||||
};
|
||||
|
||||
const char *CZombieBull::pBiteSounds[] =
|
||||
{
|
||||
"bull/bu_gore1.wav",
|
||||
"bull/bu_gore2.wav",
|
||||
"bull/bu_gore3.wav",
|
||||
};
|
||||
|
||||
const char *CZombieBull::pIdleSounds[] =
|
||||
{
|
||||
"bull/bu_idle1.wav",
|
||||
"bull/bu_idle2.wav",
|
||||
"bull/bu_idle3.wav",
|
||||
};
|
||||
|
||||
const char *CZombieBull::pAlertSounds[] =
|
||||
{
|
||||
"bull/bu_alert1.wav",
|
||||
"bull/bu_alert2.wav",
|
||||
"bull/bu_alert3.wav",
|
||||
"bull/bu_alert4.wav",
|
||||
};
|
||||
|
||||
const char *CZombieBull::pPainSounds[] =
|
||||
{
|
||||
"bull/bu_pain1.wav",
|
||||
"bull/bu_pain2.wav",
|
||||
"bull/bu_pain3.wav",
|
||||
};
|
||||
|
||||
const char *CZombieBull::pDeathSounds[] =
|
||||
{
|
||||
"bull/bu_die1.wav",
|
||||
"bull/bu_die2.wav",
|
||||
"bull/bu_die3.wav",
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Classify - indicates this monster's place in the
|
||||
// relationship table.
|
||||
//=========================================================
|
||||
int CZombieBull::Classify(void)
|
||||
{
|
||||
return CLASS_ALIEN_MONSTER;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// CheckMeleeAttack1 - bullsquid is a big guy, so has a longer
|
||||
// melee range than most monsters. This is the tailwhip attack
|
||||
//=========================================================
|
||||
BOOL CZombieBull::CheckMeleeAttack1(float flDot, float flDist)
|
||||
{
|
||||
if (m_hEnemy->pev->health <= gSkillData.bullsquidDmgWhip && flDist <= 95 && flDot >= 0.7)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// CheckMeleeAttack2 - bullsquid is a big guy, so has a longer
|
||||
// melee range than most monsters. This is the bite attack.
|
||||
// this attack will not be performed if the tailwhip attack
|
||||
// is valid.
|
||||
//=========================================================
|
||||
BOOL CZombieBull::CheckMeleeAttack2(float flDot, float flDist)
|
||||
{
|
||||
if (flDist <= 95 && flDot >= 0.7 && !HasConditions(bits_COND_CAN_MELEE_ATTACK1))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// IdleSound
|
||||
//=========================================================
|
||||
void CZombieBull::IdleSound(void)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pIdleSounds), 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// PainSound
|
||||
//=========================================================
|
||||
void CZombieBull::PainSound(void)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pPainSounds), 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// AlertSound
|
||||
//=========================================================
|
||||
void CZombieBull::AlertSound(void)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pAlertSounds), 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// HandleAnimEvent - catches the monster-specific messages
|
||||
// that occur when tagged animation frames are played.
|
||||
//=========================================================
|
||||
void CZombieBull::HandleAnimEvent(MonsterEvent_t *pEvent)
|
||||
{
|
||||
switch (pEvent->event)
|
||||
{
|
||||
case ZBULL_AE_BITE:
|
||||
{
|
||||
// SOUND HERE!
|
||||
|
||||
CBaseEntity *pHurt = CheckTraceHullAttack(90, gSkillData.zombiebullDmgBite, DMG_SLASH);
|
||||
if (pHurt)
|
||||
{
|
||||
pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_forward * 400;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Search for human repels.
|
||||
//
|
||||
CBaseEntity *pEntity = NULL;
|
||||
// iterate on all entities in the vicinity.
|
||||
while ((pEntity = UTIL_FindEntityInSphere(pEntity, pev->origin, 128)) != NULL)
|
||||
{
|
||||
if (pEntity->pev->takedamage != DAMAGE_NO)
|
||||
{
|
||||
if (FClassnameIs(pEntity->pev, "monster_hgrunt_repel"))
|
||||
{
|
||||
pEntity->TakeDamage(pev, pev, gSkillData.zombiebullDmgBite, DMG_SLASH | DMG_ALWAYSGIB);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ZBULL_AE_TAILWHIP:
|
||||
{
|
||||
// croonchy bite sound
|
||||
BiteSound();
|
||||
|
||||
CBaseEntity *pHurt = CheckTraceHullAttack(90, gSkillData.zombiebullDmgWhip, DMG_SLASH | DMG_ALWAYSGIB);
|
||||
if (pHurt)
|
||||
{
|
||||
pHurt->pev->punchangle.z = -20;
|
||||
pHurt->pev->punchangle.x = 20;
|
||||
pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_right * 16;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ZBULL_AE_THROW:
|
||||
{
|
||||
// squid throws its prey IF the prey is a client.
|
||||
CBaseEntity *pHurt = CheckTraceHullAttack(90, 0, 0);
|
||||
|
||||
if (pHurt)
|
||||
{
|
||||
// screeshake transforms the viewmodel as well as the viewangle. No problems with seeing the ends of the viewmodels.
|
||||
UTIL_ScreenShake(pHurt->pev->origin, 25.0, 1.5, 0.7, 2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ZBULL_AE_BLINK:
|
||||
break;
|
||||
|
||||
default:
|
||||
CBullsquid::HandleAnimEvent(pEvent);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Spawn
|
||||
//=========================================================
|
||||
void CZombieBull::Spawn()
|
||||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL(ENT(pev), "models/zombiebull.mdl");
|
||||
UTIL_SetSize(pev, Vector(-32, -32, 0), Vector(32, 32, 64));
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->effects = 0;
|
||||
pev->health = gSkillData.zombiebullHealth;
|
||||
m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
m_MonsterState = MONSTERSTATE_NONE;
|
||||
|
||||
m_fCanThreatDisplay = FALSE;
|
||||
|
||||
MonsterInit();
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Precache - precaches all resources this monster needs
|
||||
//=========================================================
|
||||
void CZombieBull::Precache()
|
||||
{
|
||||
PRECACHE_MODEL("models/zombiebull.mdl");
|
||||
|
||||
PRECACHE_SOUND("zombie/claw_miss2.wav");// because we use the basemonster SWIPE animation event
|
||||
|
||||
PRECACHE_SOUND_ARRAY(pAttackSounds);
|
||||
PRECACHE_SOUND_ARRAY(pBiteSounds);
|
||||
PRECACHE_SOUND_ARRAY(pIdleSounds);
|
||||
PRECACHE_SOUND_ARRAY(pAlertSounds);
|
||||
PRECACHE_SOUND_ARRAY(pPainSounds);
|
||||
PRECACHE_SOUND_ARRAY(pDeathSounds);
|
||||
|
||||
PRECACHE_SOUND("bull/bu_paw1.wav");
|
||||
|
||||
PRECACHE_SOUND("bull/bu_runstep1.wav");
|
||||
PRECACHE_SOUND("bull/bu_runstep2.wav");
|
||||
|
||||
PRECACHE_SOUND("bull/bu_walkstep1.wav");
|
||||
PRECACHE_SOUND("bull/bu_walkstep2.wav");
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// DeathSound
|
||||
//=========================================================
|
||||
void CZombieBull::DeathSound(void)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pDeathSounds), 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// AttackSound
|
||||
//=========================================================
|
||||
void CZombieBull::AttackSound(void)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pAttackSounds), 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// BiteSound
|
||||
//=========================================================
|
||||
void CZombieBull::BiteSound(void)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, RANDOM_SOUND_ARRAY(pBiteSounds), 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// GetSchedule
|
||||
//=========================================================
|
||||
Schedule_t *CZombieBull::GetSchedule(void)
|
||||
{
|
||||
switch (m_MonsterState)
|
||||
{
|
||||
case MONSTERSTATE_ALERT:
|
||||
return CBaseMonster::GetSchedule();
|
||||
|
||||
case MONSTERSTATE_COMBAT:
|
||||
{
|
||||
// dead enemy
|
||||
if (HasConditions(bits_COND_ENEMY_DEAD))
|
||||
{
|
||||
// call base class, all code to handle dead enemies is centralized there.
|
||||
return CBaseMonster::GetSchedule();
|
||||
}
|
||||
|
||||
if (HasConditions(bits_COND_NEW_ENEMY))
|
||||
{
|
||||
return GetScheduleOfType(SCHED_WAKE_ANGRY);
|
||||
}
|
||||
|
||||
if (HasConditions(bits_COND_CAN_MELEE_ATTACK1))
|
||||
{
|
||||
return GetScheduleOfType(SCHED_MELEE_ATTACK1);
|
||||
}
|
||||
|
||||
if (HasConditions(bits_COND_CAN_MELEE_ATTACK2))
|
||||
{
|
||||
return GetScheduleOfType(SCHED_MELEE_ATTACK2);
|
||||
}
|
||||
|
||||
return GetScheduleOfType(SCHED_CHASE_ENEMY);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CBaseMonster::GetSchedule();
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// Start task - selects the correct activity and performs
|
||||
// any necessary calculations to start the next task on the
|
||||
// schedule. OVERRIDDEN for bullsquid because it needs to
|
||||
// know explicitly when the last attempt to chase the enemy
|
||||
// failed, since that impacts its attack choices.
|
||||
//=========================================================
|
||||
void CZombieBull::StartTask(Task_t *pTask)
|
||||
{
|
||||
m_iTaskStatus = TASKSTATUS_RUNNING;
|
||||
|
||||
switch (pTask->iTask)
|
||||
{
|
||||
case TASK_MELEE_ATTACK2:
|
||||
{
|
||||
AttackSound();
|
||||
|
||||
CBaseMonster::StartTask(pTask);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
CBullsquid::StartTask(pTask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@
|
|||
#include "weapons.h"
|
||||
#include "soundent.h"
|
||||
#include "hornet.h"
|
||||
#include "hgrunt.h"
|
||||
|
||||
//=========================================================
|
||||
// monster-specific schedule types
|
||||
|
@ -193,11 +194,6 @@ const char *CAGrunt::pAlertSounds[] =
|
|||
//=========================================================
|
||||
int CAGrunt::IRelationship( CBaseEntity *pTarget )
|
||||
{
|
||||
if( FClassnameIs( pTarget->pev, "monster_human_grunt" ) )
|
||||
{
|
||||
return R_NM;
|
||||
}
|
||||
|
||||
return CSquadMonster::IRelationship( pTarget );
|
||||
}
|
||||
|
||||
|
@ -214,46 +210,8 @@ int CAGrunt::ISoundMask( void )
|
|||
//=========================================================
|
||||
void CAGrunt::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType )
|
||||
{
|
||||
if( ptr->iHitgroup == 10 && ( bitsDamageType & ( DMG_BULLET | DMG_SLASH | DMG_CLUB ) ) )
|
||||
{
|
||||
// hit armor
|
||||
if( pev->dmgtime != gpGlobals->time || ( RANDOM_LONG( 0, 10 ) < 1 ) )
|
||||
{
|
||||
UTIL_Ricochet( ptr->vecEndPos, RANDOM_FLOAT( 1, 2 ) );
|
||||
pev->dmgtime = gpGlobals->time;
|
||||
}
|
||||
|
||||
if( RANDOM_LONG( 0, 1 ) == 0 )
|
||||
{
|
||||
Vector vecTracerDir = vecDir;
|
||||
|
||||
vecTracerDir.x += RANDOM_FLOAT( -0.3, 0.3 );
|
||||
vecTracerDir.y += RANDOM_FLOAT( -0.3, 0.3 );
|
||||
vecTracerDir.z += RANDOM_FLOAT( -0.3, 0.3 );
|
||||
|
||||
vecTracerDir = vecTracerDir * -512;
|
||||
|
||||
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, ptr->vecEndPos );
|
||||
WRITE_BYTE( TE_TRACER );
|
||||
WRITE_COORD( ptr->vecEndPos.x );
|
||||
WRITE_COORD( ptr->vecEndPos.y );
|
||||
WRITE_COORD( ptr->vecEndPos.z );
|
||||
|
||||
WRITE_COORD( vecTracerDir.x );
|
||||
WRITE_COORD( vecTracerDir.y );
|
||||
WRITE_COORD( vecTracerDir.z );
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
flDamage -= 20;
|
||||
if( flDamage <= 0 )
|
||||
flDamage = 0.1;// don't hurt the monster much, but allow bits_COND_LIGHT_DAMAGE to be generated
|
||||
}
|
||||
else
|
||||
{
|
||||
SpawnBlood( ptr->vecEndPos, BloodColor(), flDamage );// a little surface blood.
|
||||
TraceBleed( flDamage, vecDir, ptr, bitsDamageType );
|
||||
}
|
||||
SpawnBlood( ptr->vecEndPos, BloodColor(), flDamage ); // a little surface blood.
|
||||
TraceBleed( flDamage, vecDir, ptr, bitsDamageType );
|
||||
|
||||
AddMultiDamage( pevAttacker, this, flDamage, bitsDamageType );
|
||||
}
|
||||
|
@ -263,7 +221,7 @@ void CAGrunt::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir
|
|||
//=========================================================
|
||||
void CAGrunt::StopTalking( void )
|
||||
{
|
||||
m_flNextWordTime = m_flNextSpeakTime = gpGlobals->time + 10 + RANDOM_LONG( 0, 10 );
|
||||
m_flNextWordTime = m_flNextSpeakTime = gpGlobals->time + 50 + RANDOM_LONG( 0, 10 );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
@ -322,7 +280,7 @@ void CAGrunt::PrescheduleThink( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
m_flNextWordTime = gpGlobals->time + RANDOM_FLOAT( 0.5, 1 );
|
||||
m_flNextWordTime = gpGlobals->time + RANDOM_FLOAT( 20, 25 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -492,10 +450,10 @@ void CAGrunt::HandleAnimEvent( MonsterEvent_t *pEvent )
|
|||
{
|
||||
// left foot
|
||||
case 0:
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_BODY, "player/pl_ladder2.wav", 1, ATTN_NORM, 0, 70 );
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_BODY, "zork/leftfoot2.wav", 1, ATTN_NORM, 0, 70 );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_BODY, "player/pl_ladder4.wav", 1, ATTN_NORM, 0, 70 );
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_BODY, "zork/leftfoot4.wav", 1, ATTN_NORM, 0, 70 );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -504,10 +462,10 @@ void CAGrunt::HandleAnimEvent( MonsterEvent_t *pEvent )
|
|||
switch( RANDOM_LONG( 0, 1 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_BODY, "player/pl_ladder1.wav", 1, ATTN_NORM, 0, 70 );
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_BODY, "zork/leftfoot1.wav", 1, ATTN_NORM, 0, 70 );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_BODY, "player/pl_ladder3.wav", 1, ATTN_NORM, 0 ,70);
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_BODY, "zork/leftfoot3.wav", 1, ATTN_NORM, 0 ,70);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -588,7 +546,7 @@ void CAGrunt::Spawn()
|
|||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_GREEN;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->effects = 0;
|
||||
pev->health = gSkillData.agruntHealth;
|
||||
m_flFieldOfView = 0.2;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
|
@ -598,7 +556,7 @@ void CAGrunt::Spawn()
|
|||
|
||||
m_HackedGunPos = Vector( 24, 64, 48 );
|
||||
|
||||
m_flNextSpeakTime = m_flNextWordTime = gpGlobals->time + 10 + RANDOM_LONG( 0, 10 );
|
||||
m_flNextSpeakTime = m_flNextWordTime = gpGlobals->time + 50 + RANDOM_LONG( 0, 10 );
|
||||
|
||||
MonsterInit();
|
||||
}
|
||||
|
@ -638,6 +596,12 @@ void CAGrunt::Precache()
|
|||
iAgruntMuzzleFlash = PRECACHE_MODEL( "sprites/muz4.spr" );
|
||||
|
||||
UTIL_PrecacheOther( "hornet" );
|
||||
|
||||
PRECACHE_SOUND( "zork/leftfoot2.wav" );
|
||||
PRECACHE_SOUND( "zork/leftfoot4.wav" );
|
||||
PRECACHE_SOUND( "zork/rightfoot1.wav" );
|
||||
PRECACHE_SOUND( "zork/rightfoot3.wav" );
|
||||
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
@ -925,34 +889,7 @@ BOOL CAGrunt::CheckMeleeAttack1( float flDot, float flDist )
|
|||
//=========================================================
|
||||
BOOL CAGrunt::CheckRangeAttack1( float flDot, float flDist )
|
||||
{
|
||||
if( gpGlobals->time < m_flNextHornetAttackCheck )
|
||||
{
|
||||
return m_fCanHornetAttack;
|
||||
}
|
||||
|
||||
if( HasConditions( bits_COND_SEE_ENEMY ) && flDist >= AGRUNT_MELEE_DIST && flDist <= 1024 && flDot >= 0.5 && NoFriendlyFire() )
|
||||
{
|
||||
TraceResult tr;
|
||||
Vector vecArmPos, vecArmDir;
|
||||
|
||||
// verify that a shot fired from the gun will hit the enemy before the world.
|
||||
// !!!LATER - we may wish to do something different for projectile weapons as opposed to instant-hit
|
||||
UTIL_MakeVectors( pev->angles );
|
||||
GetAttachment( 0, vecArmPos, vecArmDir );
|
||||
//UTIL_TraceLine( vecArmPos, vecArmPos + gpGlobals->v_forward * 256, ignore_monsters, ENT( pev ), &tr );
|
||||
UTIL_TraceLine( vecArmPos, m_hEnemy->BodyTarget( vecArmPos ), dont_ignore_monsters, ENT( pev ), &tr );
|
||||
|
||||
if( tr.flFraction == 1.0 || tr.pHit == m_hEnemy->edict() )
|
||||
{
|
||||
m_flNextHornetAttackCheck = gpGlobals->time + RANDOM_FLOAT( 2, 5 );
|
||||
m_fCanHornetAttack = TRUE;
|
||||
return m_fCanHornetAttack;
|
||||
}
|
||||
}
|
||||
|
||||
m_flNextHornetAttackCheck = gpGlobals->time + 0.2;// don't check for half second if this check wasn't successful
|
||||
m_fCanHornetAttack = FALSE;
|
||||
return m_fCanHornetAttack;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
|
|
@ -21,74 +21,13 @@
|
|||
#include "weapons.h"
|
||||
#include "nodes.h"
|
||||
#include "effects.h"
|
||||
#include "apache.h"
|
||||
|
||||
extern DLL_GLOBAL int g_iSkillLevel;
|
||||
|
||||
#define SF_WAITFORTRIGGER (0x04 | 0x40) // UNDONE: Fix!
|
||||
#define SF_NOWRECKAGE 0x08
|
||||
|
||||
class CApache : public CBaseMonster
|
||||
{
|
||||
int Save( CSave &save );
|
||||
int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
int Classify( void ) { return CLASS_HUMAN_MILITARY; };
|
||||
int BloodColor( void ) { return DONT_BLEED; }
|
||||
void Killed( entvars_t *pevAttacker, int iGib );
|
||||
void GibMonster( void );
|
||||
|
||||
void SetObjectCollisionBox( void )
|
||||
{
|
||||
pev->absmin = pev->origin + Vector( -300, -300, -172 );
|
||||
pev->absmax = pev->origin + Vector( 300, 300, 8 );
|
||||
}
|
||||
|
||||
void EXPORT HuntThink( void );
|
||||
void EXPORT FlyTouch( CBaseEntity *pOther );
|
||||
void EXPORT CrashTouch( CBaseEntity *pOther );
|
||||
void EXPORT DyingThink( void );
|
||||
void EXPORT StartupUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void EXPORT NullThink( void );
|
||||
|
||||
void ShowDamage( void );
|
||||
void Flight( void );
|
||||
void FireRocket( void );
|
||||
BOOL FireGun( void );
|
||||
|
||||
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
|
||||
void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType );
|
||||
|
||||
int m_iRockets;
|
||||
float m_flForce;
|
||||
float m_flNextRocket;
|
||||
|
||||
Vector m_vecTarget;
|
||||
Vector m_posTarget;
|
||||
|
||||
Vector m_vecDesired;
|
||||
Vector m_posDesired;
|
||||
|
||||
Vector m_vecGoal;
|
||||
|
||||
Vector m_angGun;
|
||||
float m_flLastSeen;
|
||||
float m_flPrevSeen;
|
||||
|
||||
int m_iSoundState; // don't save this
|
||||
|
||||
int m_iSpriteTexture;
|
||||
int m_iExplode;
|
||||
int m_iBodyGibs;
|
||||
|
||||
float m_flGoalSpeed;
|
||||
|
||||
int m_iDoSmokePuff;
|
||||
CBeam *m_pBeam;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_apache, CApache )
|
||||
|
||||
TYPEDESCRIPTION CApache::m_SaveData[] =
|
||||
|
@ -122,7 +61,7 @@ void CApache::Spawn( void )
|
|||
pev->movetype = MOVETYPE_FLY;
|
||||
pev->solid = SOLID_BBOX;
|
||||
|
||||
SET_MODEL( ENT( pev ), "models/apache.mdl" );
|
||||
SET_MODEL( ENT( pev ), (char*)STRING( pev->model ) );
|
||||
UTIL_SetSize( pev, Vector( -32, -32, -64 ), Vector( 32, 32, 0 ) );
|
||||
UTIL_SetOrigin( pev, pev->origin );
|
||||
|
||||
|
@ -154,7 +93,8 @@ void CApache::Spawn( void )
|
|||
|
||||
void CApache::Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/apache.mdl" );
|
||||
PRECACHE_MODEL( "models/apache2.mdl" );
|
||||
PRECACHE_MODEL( "models/huey_apache.mdl" );
|
||||
|
||||
PRECACHE_SOUND( "apache/ap_rotor1.wav" );
|
||||
PRECACHE_SOUND( "apache/ap_rotor2.wav" );
|
||||
|
@ -397,6 +337,14 @@ void CApache::DyingThink( void )
|
|||
WRITE_BYTE( BREAK_METAL );
|
||||
MESSAGE_END();
|
||||
|
||||
//
|
||||
// AI Trigger target on death.
|
||||
//
|
||||
if( m_iTriggerCondition == AITRIGGER_DEATH && !FStringNull( m_iszTriggerTarget ) )
|
||||
{
|
||||
FireTargets( STRING( m_iszTriggerTarget ), this, this, USE_TOGGLE, 0 );
|
||||
m_iTriggerCondition = AITRIGGER_NONE;
|
||||
}
|
||||
SetThink( &CBaseEntity::SUB_Remove );
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
@ -915,8 +863,8 @@ void CApache::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir
|
|||
}
|
||||
else
|
||||
{
|
||||
// do half damage in the body
|
||||
// AddMultiDamage( pevAttacker, this, flDamage / 2.0, bitsDamageType );
|
||||
// do tenth damage in the body
|
||||
AddMultiDamage( pevAttacker, this, flDamage / 10.0, bitsDamageType );
|
||||
UTIL_Ricochet( ptr->vecEndPos, 2.0 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/***
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****/
|
||||
|
||||
#ifndef APACHE_H
|
||||
#define APACHE_H
|
||||
|
||||
class CApache : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
int Save( CSave &save );
|
||||
int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
int Classify( void ) { return CLASS_HUMAN_MILITARY; };
|
||||
int BloodColor( void ) { return DONT_BLEED; }
|
||||
void Killed( entvars_t *pevAttacker, int iGib );
|
||||
void GibMonster( void );
|
||||
|
||||
void SetObjectCollisionBox( void )
|
||||
{
|
||||
pev->absmin = pev->origin + Vector( -300, -300, -172);
|
||||
pev->absmax = pev->origin + Vector(300, 300, 8);
|
||||
}
|
||||
|
||||
void EXPORT HuntThink( void );
|
||||
void EXPORT FlyTouch( CBaseEntity *pOther );
|
||||
void EXPORT CrashTouch( CBaseEntity *pOther );
|
||||
void EXPORT DyingThink( void );
|
||||
void EXPORT StartupUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
void EXPORT NullThink( void );
|
||||
|
||||
void ShowDamage( void );
|
||||
void Flight( void );
|
||||
void FireRocket( void );
|
||||
virtual BOOL FireGun( void );
|
||||
|
||||
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
|
||||
void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
|
||||
|
||||
int m_iRockets;
|
||||
float m_flForce;
|
||||
float m_flNextRocket;
|
||||
|
||||
Vector m_vecTarget;
|
||||
Vector m_posTarget;
|
||||
|
||||
Vector m_vecDesired;
|
||||
Vector m_posDesired;
|
||||
|
||||
Vector m_vecGoal;
|
||||
|
||||
Vector m_angGun;
|
||||
float m_flLastSeen;
|
||||
float m_flPrevSeen;
|
||||
|
||||
int m_iSoundState; // don't save this
|
||||
|
||||
int m_iSpriteTexture;
|
||||
int m_iExplode;
|
||||
int m_iBodyGibs;
|
||||
|
||||
float m_flGoalSpeed;
|
||||
|
||||
int m_iDoSmokePuff;
|
||||
CBeam *m_pBeam;
|
||||
};
|
||||
#endif // APACHE_H
|
199
dlls/barney.cpp
199
dlls/barney.cpp
|
@ -27,6 +27,25 @@
|
|||
#include "scripted.h"
|
||||
#include "weapons.h"
|
||||
#include "soundent.h"
|
||||
#include "barney.h"
|
||||
|
||||
//
|
||||
// Barney special flags
|
||||
//
|
||||
|
||||
#define BF_ZOMBIECOP 1
|
||||
|
||||
//
|
||||
// Barney skins
|
||||
//
|
||||
enum
|
||||
{
|
||||
SKIN_NORMAL_COP = 0,
|
||||
SKIN_ZOMBIE_COP_YOUNG,
|
||||
SKIN_ZOMBIE_COP_OLD,
|
||||
SKIN_ASYLUM_GUARD,
|
||||
SKIN_ZOMBIE_ASYLUM_GUARD
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
|
@ -40,54 +59,6 @@
|
|||
#define BARNEY_BODY_GUNDRAWN 1
|
||||
#define BARNEY_BODY_GUNGONE 2
|
||||
|
||||
class CBarney : public CTalkMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void SetYawSpeed( void );
|
||||
int ISoundMask( void );
|
||||
void BarneyFirePistol( void );
|
||||
void AlertSound( void );
|
||||
int Classify( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
|
||||
void RunTask( Task_t *pTask );
|
||||
void StartTask( Task_t *pTask );
|
||||
virtual int ObjectCaps( void ) { return CTalkMonster :: ObjectCaps() | FCAP_IMPULSE_USE; }
|
||||
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType);
|
||||
BOOL CheckRangeAttack1( float flDot, float flDist );
|
||||
|
||||
void DeclineFollowing( void );
|
||||
|
||||
// Override these to set behavior
|
||||
Schedule_t *GetScheduleOfType( int Type );
|
||||
Schedule_t *GetSchedule( void );
|
||||
MONSTERSTATE GetIdealState( void );
|
||||
|
||||
void DeathSound( void );
|
||||
void PainSound( void );
|
||||
|
||||
void TalkInit( void );
|
||||
|
||||
void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
|
||||
void Killed( entvars_t *pevAttacker, int iGib );
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
BOOL m_fGunDrawn;
|
||||
float m_painTime;
|
||||
float m_checkAttackTime;
|
||||
BOOL m_lastAttackCheck;
|
||||
|
||||
// UNDONE: What is this for? It isn't used?
|
||||
float m_flPlayerDamage;// how much pain has the player inflicted on me?
|
||||
|
||||
CUSTOM_SCHEDULES
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_barney, CBarney )
|
||||
|
||||
TYPEDESCRIPTION CBarney::m_SaveData[] =
|
||||
|
@ -97,6 +68,7 @@ TYPEDESCRIPTION CBarney::m_SaveData[] =
|
|||
DEFINE_FIELD( CBarney, m_checkAttackTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( CBarney, m_lastAttackCheck, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( CBarney, m_flPlayerDamage, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( CBarney, m_iBarneyFlags, FIELD_INTEGER ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CBarney, CTalkMonster )
|
||||
|
@ -254,6 +226,9 @@ int CBarney::ISoundMask( void)
|
|||
//=========================================================
|
||||
int CBarney::Classify( void )
|
||||
{
|
||||
if( IsZombieCop() )
|
||||
return CLASS_ALIEN_MONSTER;
|
||||
|
||||
return CLASS_PLAYER_ALLY;
|
||||
}
|
||||
|
||||
|
@ -343,7 +318,21 @@ void CBarney::BarneyFirePistol( void )
|
|||
SetBlending( 0, angDir.x );
|
||||
pev->effects = EF_MUZZLEFLASH;
|
||||
|
||||
FireBullets( 1, vecShootOrigin, vecShootDir, VECTOR_CONE_2DEGREES, 1024, BULLET_MONSTER_9MM );
|
||||
Vector vecSpread;
|
||||
|
||||
if( m_hEnemy == NULL || !m_hEnemy->IsPlayer() )
|
||||
{
|
||||
// Higher chance to hit target.
|
||||
vecSpread = VECTOR_CONE_2DEGREES;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allow barney to miss player to avoid too much accuracy.
|
||||
vecSpread = VECTOR_CONE_6DEGREES;
|
||||
}
|
||||
|
||||
// Fire bullet.
|
||||
FireBullets( 1, vecShootOrigin, vecShootDir, vecSpread, 1024, BULLET_MONSTER_9MM );
|
||||
|
||||
int pitchShift = RANDOM_LONG( 0, 20 );
|
||||
|
||||
|
@ -395,7 +384,12 @@ void CBarney::Spawn()
|
|||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL( ENT( pev ), "models/barney.mdl" );
|
||||
char* szModel = (char*)STRING( pev->model );
|
||||
if( !szModel || !*szModel )
|
||||
{
|
||||
szModel = "models/barney.mdl";
|
||||
}
|
||||
SET_MODEL( ENT( pev ), szModel );
|
||||
UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
|
@ -413,6 +407,56 @@ void CBarney::Spawn()
|
|||
|
||||
MonsterInit();
|
||||
SetUse( &CTalkMonster::FollowerUse );
|
||||
|
||||
// Cops use a lower voice pitch.
|
||||
m_voicePitch = RANDOM_LONG( 95, 96 );
|
||||
|
||||
m_iBarneyFlags = 0;
|
||||
|
||||
// If this is a zombie cop.
|
||||
if( pev->spawnflags & SF_MONSTER_ZOMBIECOP )
|
||||
{
|
||||
m_iBarneyFlags |= BF_ZOMBIECOP;
|
||||
|
||||
// Convert to zombie skin.
|
||||
switch( pev->skin )
|
||||
{
|
||||
// Regular zombie skin.
|
||||
case SKIN_NORMAL_COP:
|
||||
pev->skin = SKIN_ZOMBIE_COP_YOUNG + RANDOM_LONG( 0, 1 );
|
||||
break;
|
||||
// Zombie asylum guard.
|
||||
case SKIN_ASYLUM_GUARD:
|
||||
pev->skin = SKIN_ZOMBIE_ASYLUM_GUARD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert to normal skin.
|
||||
switch( pev->skin )
|
||||
{
|
||||
// Young/old skin.
|
||||
case SKIN_ZOMBIE_COP_YOUNG:
|
||||
case SKIN_ZOMBIE_COP_OLD:
|
||||
pev->skin = SKIN_NORMAL_COP;
|
||||
break;
|
||||
// Asylum guard.
|
||||
case SKIN_ZOMBIE_ASYLUM_GUARD:
|
||||
pev->skin = SKIN_ASYLUM_GUARD;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent zombie cops from being 'used'.
|
||||
if( IsZombieCop() )
|
||||
{
|
||||
SetUse( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
@ -421,6 +465,7 @@ void CBarney::Spawn()
|
|||
void CBarney::Precache()
|
||||
{
|
||||
PRECACHE_MODEL( "models/barney.mdl" );
|
||||
PRECACHE_MODEL( "models/pilot.mdl" );
|
||||
|
||||
PRECACHE_SOUND( "barney/ba_attack1.wav" );
|
||||
PRECACHE_SOUND( "barney/ba_attack2.wav" );
|
||||
|
@ -498,6 +543,10 @@ int CBarney::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float
|
|||
if( !IsAlive() || pev->deadflag == DEAD_DYING )
|
||||
return ret;
|
||||
|
||||
// Do not speak about players harming me if I am a zombie.
|
||||
if( IsZombieCop() )
|
||||
return ret;
|
||||
|
||||
if( m_MonsterState != MONSTERSTATE_PRONE && ( pevAttacker->flags & FL_CLIENT ) )
|
||||
{
|
||||
m_flPlayerDamage += flDamage;
|
||||
|
@ -580,7 +629,7 @@ void CBarney::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir
|
|||
{
|
||||
case HITGROUP_CHEST:
|
||||
case HITGROUP_STOMACH:
|
||||
if (bitsDamageType & ( DMG_BULLET | DMG_SLASH | DMG_BLAST ) )
|
||||
if( ( bitsDamageType & ( DMG_BULLET | DMG_SLASH | DMG_BLAST ) )&& HasKevlar() )
|
||||
{
|
||||
flDamage = flDamage / 2;
|
||||
}
|
||||
|
@ -764,6 +813,54 @@ void CBarney::DeclineFollowing( void )
|
|||
PlaySentence( "BA_POK", 2, VOL_NORM, ATTN_NORM );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// IdleRespond
|
||||
// Respond to a previous question
|
||||
//=========================================================
|
||||
void CBarney::IdleRespond( void )
|
||||
{
|
||||
if( IsZombieCop() )
|
||||
return;
|
||||
|
||||
CTalkMonster::IdleRespond();
|
||||
}
|
||||
|
||||
int CBarney::FOkToSpeak( void )
|
||||
{
|
||||
if( IsZombieCop() )
|
||||
return FALSE;
|
||||
|
||||
return CTalkMonster::FOkToSpeak();
|
||||
}
|
||||
|
||||
BOOL CBarney::IsZombieCop( void ) const
|
||||
{
|
||||
return ( m_iBarneyFlags & BF_ZOMBIECOP );
|
||||
}
|
||||
|
||||
BOOL CBarney::HasKevlar() const
|
||||
{
|
||||
return pev->skin == SKIN_ASYLUM_GUARD || pev->skin == SKIN_ZOMBIE_ASYLUM_GUARD;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Only called by monstermaker.
|
||||
// Used to fix up Barney skin.
|
||||
//=========================================================
|
||||
void CBarney::FixupBarneySkin( BOOL bZombieCop )
|
||||
{
|
||||
if( bZombieCop )
|
||||
{
|
||||
// Map they21
|
||||
//
|
||||
// This Barney should attack players but use regular skin.
|
||||
if( FStrEq( STRING( gpGlobals->mapname ), "they21" ) && FStrEq( STRING( pev->targetname ), "discoverer" ) )
|
||||
{
|
||||
pev->skin = SKIN_NORMAL_COP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// DEAD BARNEY PROP
|
||||
//
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/***
|
||||
*
|
||||
* 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 BARNEY_H
|
||||
#define BARNEY_H
|
||||
|
||||
#include "talkmonster.h"
|
||||
|
||||
class CBarney : public CTalkMonster
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
void SetYawSpeed(void);
|
||||
int ISoundMask(void);
|
||||
void BarneyFirePistol(void);
|
||||
void AlertSound(void);
|
||||
int Classify(void);
|
||||
void HandleAnimEvent(MonsterEvent_t *pEvent);
|
||||
|
||||
void RunTask(Task_t *pTask);
|
||||
void StartTask(Task_t *pTask);
|
||||
virtual int ObjectCaps(void) { return CTalkMonster::ObjectCaps() | FCAP_IMPULSE_USE; }
|
||||
int TakeDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType);
|
||||
BOOL CheckRangeAttack1(float flDot, float flDist);
|
||||
|
||||
void DeclineFollowing(void);
|
||||
|
||||
// Override these to set behavior
|
||||
Schedule_t *GetScheduleOfType(int Type);
|
||||
Schedule_t *GetSchedule(void);
|
||||
MONSTERSTATE GetIdealState(void);
|
||||
|
||||
void DeathSound(void);
|
||||
void PainSound(void);
|
||||
|
||||
void TalkInit(void);
|
||||
|
||||
void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
|
||||
void Killed(entvars_t *pevAttacker, int iGib);
|
||||
|
||||
virtual int Save(CSave &save);
|
||||
virtual int Restore(CRestore &restore);
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
BOOL m_fGunDrawn;
|
||||
float m_painTime;
|
||||
float m_checkAttackTime;
|
||||
BOOL m_lastAttackCheck;
|
||||
|
||||
// UNDONE: What is this for? It isn't used?
|
||||
float m_flPlayerDamage;// how much pain has the player inflicted on me?
|
||||
|
||||
CUSTOM_SCHEDULES;
|
||||
|
||||
void IdleRespond(void);
|
||||
int FOkToSpeak(void);
|
||||
|
||||
BOOL IsZombieCop() const;
|
||||
BOOL HasKevlar() const;
|
||||
|
||||
void FixupBarneySkin( BOOL bZombieCop );
|
||||
|
||||
int m_iBarneyFlags;
|
||||
};
|
||||
|
||||
#endif // BARNEY_H
|
|
@ -26,51 +26,12 @@
|
|||
#include "decals.h"
|
||||
#include "soundent.h"
|
||||
#include "game.h"
|
||||
#include "bullsquid.h"
|
||||
|
||||
#define SQUID_SPRINT_DIST 256 // how close the squid has to get before starting to sprint and refusing to swerve
|
||||
|
||||
int iSquidSpitSprite;
|
||||
|
||||
//=========================================================
|
||||
// monster-specific schedule types
|
||||
//=========================================================
|
||||
enum
|
||||
{
|
||||
SCHED_SQUID_HURTHOP = LAST_COMMON_SCHEDULE + 1,
|
||||
SCHED_SQUID_SMELLFOOD,
|
||||
SCHED_SQUID_SEECRAB,
|
||||
SCHED_SQUID_EAT,
|
||||
SCHED_SQUID_SNIFF_AND_EAT,
|
||||
SCHED_SQUID_WALLOW
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// monster-specific tasks
|
||||
//=========================================================
|
||||
enum
|
||||
{
|
||||
TASK_SQUID_HOPTURN = LAST_COMMON_TASK + 1
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Bullsquid's spit projectile
|
||||
//=========================================================
|
||||
class CSquidSpit : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
|
||||
static void Shoot( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity );
|
||||
void Touch( CBaseEntity *pOther );
|
||||
void EXPORT Animate( void );
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
int m_maxFrame;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( squidspit, CSquidSpit )
|
||||
|
||||
TYPEDESCRIPTION CSquidSpit::m_SaveData[] =
|
||||
|
@ -89,7 +50,7 @@ void CSquidSpit::Spawn( void )
|
|||
pev->rendermode = kRenderTransAlpha;
|
||||
pev->renderamt = 255;
|
||||
|
||||
SET_MODEL( ENT( pev ), "sprites/bigspit.spr" );
|
||||
SET_MODEL( ENT( pev ), "sprites/redbspit.spr" );
|
||||
pev->frame = 0;
|
||||
pev->scale = 0.5;
|
||||
|
||||
|
@ -184,46 +145,6 @@ void CSquidSpit::Touch( CBaseEntity *pOther )
|
|||
#define BSQUID_AE_HOP ( 5 )
|
||||
#define BSQUID_AE_THROW ( 6 )
|
||||
|
||||
class CBullsquid : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void SetYawSpeed( void );
|
||||
int ISoundMask( void );
|
||||
int Classify( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
void IdleSound( void );
|
||||
void PainSound( void );
|
||||
void DeathSound( void );
|
||||
void AlertSound( void );
|
||||
void AttackSound( void );
|
||||
void StartTask( Task_t *pTask );
|
||||
void RunTask( Task_t *pTask );
|
||||
BOOL CheckMeleeAttack1( float flDot, float flDist );
|
||||
BOOL CheckMeleeAttack2( float flDot, float flDist );
|
||||
BOOL CheckRangeAttack1( float flDot, float flDist );
|
||||
void RunAI( void );
|
||||
BOOL FValidateHintType( short sHint );
|
||||
Schedule_t *GetSchedule( void );
|
||||
Schedule_t *GetScheduleOfType( int Type );
|
||||
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
|
||||
int IRelationship( CBaseEntity *pTarget );
|
||||
int IgnoreConditions( void );
|
||||
MONSTERSTATE GetIdealState( void );
|
||||
|
||||
int Save( CSave &save );
|
||||
int Restore( CRestore &restore );
|
||||
|
||||
CUSTOM_SCHEDULES
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
BOOL m_fCanThreatDisplay;// this is so the squid only does the "I see a headcrab!" dance one time.
|
||||
|
||||
float m_flLastHurtTime;// we keep track of this, because if something hurts a squid, it will forget about its love of headcrabs for a while.
|
||||
float m_flNextSpitTime;// last time the bullsquid used the spit attack.
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_bullchicken, CBullsquid )
|
||||
|
||||
TYPEDESCRIPTION CBullsquid::m_SaveData[] =
|
||||
|
@ -692,9 +613,9 @@ void CBullsquid::Precache()
|
|||
{
|
||||
PRECACHE_MODEL( "models/bullsquid.mdl" );
|
||||
|
||||
PRECACHE_MODEL( "sprites/bigspit.spr" );// spit projectile.
|
||||
PRECACHE_MODEL( "sprites/redbspit.spr" );// spit projectile.
|
||||
|
||||
iSquidSpitSprite = PRECACHE_MODEL( "sprites/tinyspit.spr" );// client side spittle.
|
||||
iSquidSpitSprite = PRECACHE_MODEL( "sprites/redtspit.spr" );// client side spittle.
|
||||
|
||||
PRECACHE_SOUND( "zombie/claw_miss2.wav" );// because we use the basemonster SWIPE animation event
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/***
|
||||
*
|
||||
* 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 BULLSQUID_H
|
||||
#define BULLSQUID_H
|
||||
|
||||
//=========================================================
|
||||
// monster-specific schedule types
|
||||
//=========================================================
|
||||
enum
|
||||
{
|
||||
SCHED_SQUID_HURTHOP = LAST_COMMON_SCHEDULE + 1,
|
||||
SCHED_SQUID_SMELLFOOD,
|
||||
SCHED_SQUID_SEECRAB,
|
||||
SCHED_SQUID_EAT,
|
||||
SCHED_SQUID_SNIFF_AND_EAT,
|
||||
SCHED_SQUID_WALLOW,
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// monster-specific tasks
|
||||
//=========================================================
|
||||
enum
|
||||
{
|
||||
TASK_SQUID_HOPTURN = LAST_COMMON_TASK + 1,
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Bullsquid's spit projectile
|
||||
//=========================================================
|
||||
class CSquidSpit : public CBaseEntity
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
|
||||
static void Shoot( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity );
|
||||
void Touch( CBaseEntity *pOther );
|
||||
void EXPORT Animate( void );
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
int m_maxFrame;
|
||||
};
|
||||
|
||||
class CBullsquid : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void SetYawSpeed( void );
|
||||
int ISoundMask( void );
|
||||
int Classify ( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
void IdleSound( void );
|
||||
void PainSound( void );
|
||||
void DeathSound( void );
|
||||
void AlertSound ( void );
|
||||
void AttackSound( void );
|
||||
void StartTask ( Task_t *pTask );
|
||||
void RunTask ( Task_t *pTask );
|
||||
BOOL CheckMeleeAttack1 ( float flDot, float flDist );
|
||||
BOOL CheckMeleeAttack2 ( float flDot, float flDist );
|
||||
BOOL CheckRangeAttack1 ( float flDot, float flDist );
|
||||
void RunAI( void );
|
||||
BOOL FValidateHintType ( short sHint );
|
||||
Schedule_t *GetSchedule( void );
|
||||
Schedule_t *GetScheduleOfType ( int Type );
|
||||
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
|
||||
int IRelationship ( CBaseEntity *pTarget );
|
||||
int IgnoreConditions ( void );
|
||||
MONSTERSTATE GetIdealState ( void );
|
||||
|
||||
int Save( CSave &save );
|
||||
int Restore( CRestore &restore );
|
||||
|
||||
CUSTOM_SCHEDULES;
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
BOOL m_fCanThreatDisplay;// this is so the squid only does the "I see a headcrab!" dance one time.
|
||||
|
||||
float m_flLastHurtTime;// we keep track of this, because if something hurts a squid, it will forget about its love of headcrabs for a while.
|
||||
float m_flNextSpitTime;// last time the bullsquid used the spit attack.
|
||||
};
|
||||
#endif // BULLSQUID_H
|
|
@ -101,6 +101,7 @@ typedef void(CBaseEntity::*USEPTR)( CBaseEntity *pActivator, CBaseEntity *pCalle
|
|||
#define CLASS_PLAYER_ALLY 11
|
||||
#define CLASS_PLAYER_BIOWEAPON 12 // hornets and snarks.launched by players
|
||||
#define CLASS_ALIEN_BIOWEAPON 13 // hornets and snarks.launched by the alien menace
|
||||
#define CLASS_SKELETON 14
|
||||
#define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures.
|
||||
|
||||
class CBaseEntity;
|
||||
|
@ -340,6 +341,10 @@ public:
|
|||
int ammo_uranium;
|
||||
int ammo_hornets;
|
||||
int ammo_argrens;
|
||||
int ammo_ap9;
|
||||
int ammo_taurus;
|
||||
int ammo_sniper;
|
||||
|
||||
//Special stuff for grenades and satchels.
|
||||
float m_flStartThrow;
|
||||
float m_flReleaseThrow;
|
||||
|
|
|
@ -748,6 +748,8 @@ void ClientPrecache( void )
|
|||
PRECACHE_SOUND( "debris/wood3.wav" );
|
||||
|
||||
PRECACHE_SOUND( "plats/train_use1.wav" ); // use a train
|
||||
PRECACHE_SOUND( "plats/train_use2.wav" );
|
||||
PRECACHE_SOUND( "plats/train_use6.wav" );
|
||||
|
||||
PRECACHE_SOUND( "buttons/spark5.wav" ); // hit computer texture
|
||||
PRECACHE_SOUND( "buttons/spark6.wav" );
|
||||
|
@ -787,6 +789,8 @@ void ClientPrecache( void )
|
|||
|
||||
if( giPrecacheGrunt )
|
||||
UTIL_PrecacheOther( "monster_human_grunt" );
|
||||
|
||||
UTIL_PrecacheOther( "monster_th_cyberfranklin" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1623,6 +1627,18 @@ void UpdateClientData( const struct edict_s *ent, int sendweapons, struct client
|
|||
cd->vuser2.y = ( (CRpg *)pl->m_pActiveItem )->m_fSpotActive;
|
||||
cd->vuser2.z = ( (CRpg *)pl->m_pActiveItem )->m_cActiveRockets;
|
||||
}
|
||||
else if( pl->m_pActiveItem->m_iId == WEAPON_AP9 )
|
||||
{
|
||||
cd->vuser2.y = pl->ammo_ap9;
|
||||
}
|
||||
else if( pl->m_pActiveItem->m_iId == WEAPON_TAURUS )
|
||||
{
|
||||
cd->vuser2.y = pl->ammo_taurus;
|
||||
}
|
||||
else if( pl->m_pActiveItem->m_iId == WEAPON_EINAR1 || pl->m_pActiveItem->m_iId == WEAPON_HKG36 )
|
||||
{
|
||||
cd->vuser2.y = pl->ammo_sniper;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1535,6 +1535,18 @@ 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_AP9:
|
||||
pEntity->TraceAttack( pevAttacker, gSkillData.plrDmgAP9, vecDir, &tr, DMG_BULLET );
|
||||
break;
|
||||
case BULLET_PLAYER_CHAINGUN:
|
||||
pEntity->TraceAttack( pevAttacker, gSkillData.plrDmgMP5, vecDir, &tr, DMG_BULLET );
|
||||
break;
|
||||
case BULLET_PLAYER_SNIPER:
|
||||
pEntity->TraceAttack( pevAttacker, gSkillData.plrDmgSniper, vecDir, &tr, DMG_BULLET );
|
||||
break;
|
||||
case BULLET_PLAYER_TAURUS:
|
||||
pEntity->TraceAttack( pevAttacker, gSkillData.plrDmgTaurus, vecDir, &tr, DMG_BULLET );
|
||||
break;
|
||||
case BULLET_NONE: // FIX
|
||||
pEntity->TraceAttack( pevAttacker, 50, vecDir, &tr, DMG_CLUB );
|
||||
TEXTURETYPE_PlaySound( &tr, vecSrc, vecEnd, iBulletType );
|
||||
|
|
|
@ -62,6 +62,9 @@ void CCrowbar::Precache( void )
|
|||
PRECACHE_SOUND( "weapons/cbar_hitbod2.wav" );
|
||||
PRECACHE_SOUND( "weapons/cbar_hitbod3.wav" );
|
||||
PRECACHE_SOUND( "weapons/cbar_miss1.wav" );
|
||||
PRECACHE_SOUND( "kelly/cbar_hitkelly1.wav" );
|
||||
PRECACHE_SOUND( "kelly/cbar_hitkelly2.wav" );
|
||||
PRECACHE_SOUND( "kelly/cbar_hitkelly3.wav" );
|
||||
|
||||
m_usCrowbar = PRECACHE_EVENT( 1, "events/crowbar.sc" );
|
||||
}
|
||||
|
@ -242,19 +245,40 @@ int CCrowbar::Swing( int fFirst )
|
|||
{
|
||||
if( pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE )
|
||||
{
|
||||
// play thwack or smack sound
|
||||
switch( RANDOM_LONG( 0, 2 ) )
|
||||
// Skeletons make different hit sounds.
|
||||
if( pEntity->Classify() == CLASS_SKELETON )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 2:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
// play thwack or smack sound
|
||||
switch( RANDOM_LONG( 0, 2 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "kelly/cbar_hitkelly1.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "kelly/cbar_hitkelly2.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 2:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "kelly/cbar_hitkelly3.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// play thwack or smack sound
|
||||
switch( RANDOM_LONG( 0, 2 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hitbod1.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hitbod2.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
case 2:
|
||||
EMIT_SOUND( ENT( m_pPlayer->pev ), CHAN_ITEM, "weapons/cbar_hitbod3.wav", 1, ATTN_NORM );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = CROWBAR_BODYHIT_VOLUME;
|
||||
if( !pEntity->IsAlive() )
|
||||
return TRUE;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "effects.h"
|
||||
#include "customentity.h"
|
||||
#include "gamerules.h"
|
||||
#include "flame.h"
|
||||
|
||||
#define EGON_PRIMARY_VOLUME 450
|
||||
#define EGON_BEAM_SPRITE "sprites/xbeam1.spr"
|
||||
|
@ -80,6 +81,10 @@ void CEgon::Precache( void )
|
|||
|
||||
PRECACHE_SOUND( "weapons/357_cock1.wav" );
|
||||
|
||||
PRECACHE_SOUND( "weapons/flmfire2.wav" );
|
||||
|
||||
UTIL_PrecacheOther( "flame" );
|
||||
|
||||
m_usEgonFire = PRECACHE_EVENT( 1, "events/egon_fire.sc" );
|
||||
m_usEgonStop = PRECACHE_EVENT( 1, "events/egon_stop.sc" );
|
||||
}
|
||||
|
@ -232,8 +237,59 @@ void CEgon::Attack( void )
|
|||
|
||||
void CEgon::PrimaryAttack( void )
|
||||
{
|
||||
m_fireMode = FIRE_WIDE;
|
||||
Attack();
|
||||
// don't fire underwater
|
||||
if( m_pPlayer->pev->waterlevel == 3 )
|
||||
{
|
||||
PlayEmptySound();
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay( 0.2 );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !HasAmmo() )
|
||||
{
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.25;
|
||||
PlayEmptySound();
|
||||
return;
|
||||
}
|
||||
|
||||
m_pPlayer->m_iWeaponVolume = EGON_PRIMARY_VOLUME;
|
||||
|
||||
// player "shoot" animation
|
||||
m_pPlayer->SetAnimation( PLAYER_ATTACK1 );
|
||||
|
||||
UseAmmo( 1 );
|
||||
|
||||
int flags;
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
flags = FEV_NOTHOST;
|
||||
#else
|
||||
flags = 0;
|
||||
#endif
|
||||
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usEgonFire, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
Vector position, velocity;
|
||||
Vector forward, right, up;
|
||||
|
||||
UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle );
|
||||
|
||||
forward = gpGlobals->v_forward;
|
||||
right = gpGlobals->v_right;
|
||||
up = gpGlobals->v_up;
|
||||
|
||||
position = m_pPlayer->pev->origin + m_pPlayer->pev->view_ofs;
|
||||
position = position + forward * 16;
|
||||
position = position + right * RANDOM_FLOAT( 4, 6 );
|
||||
position = position + up * RANDOM_FLOAT( 1, 2 );
|
||||
|
||||
velocity = forward * 400;
|
||||
velocity = velocity + right * ( RANDOM_LONG(0, 1 ) ? 16 : -16 );
|
||||
velocity = velocity + up * ( RANDOM_LONG( 0, 1 ) ? 16 : -8 );
|
||||
|
||||
CFlame::Shoot( m_pPlayer->pev, position, velocity );
|
||||
#endif
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay( 0.2f );
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.1;
|
||||
}
|
||||
|
||||
void CEgon::Fire( const Vector &vecOrigSrc, const Vector &vecDir )
|
||||
|
@ -475,9 +531,6 @@ void CEgon::WeaponIdle( void )
|
|||
if( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() )
|
||||
return;
|
||||
|
||||
if( m_fireState != FIRE_OFF )
|
||||
EndAttack();
|
||||
|
||||
int iAnim;
|
||||
|
||||
float flRand = RANDOM_FLOAT( 0, 1 );
|
||||
|
@ -519,13 +572,13 @@ class CEgonAmmo : public CBasePlayerAmmo
|
|||
void Spawn( void )
|
||||
{
|
||||
Precache();
|
||||
SET_MODEL( ENT( pev ), "models/w_chainammo.mdl" );
|
||||
SET_MODEL( ENT( pev ), "models/w_gas.mdl" );
|
||||
CBasePlayerAmmo::Spawn();
|
||||
}
|
||||
|
||||
void Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/w_chainammo.mdl" );
|
||||
PRECACHE_MODEL( "models/w_gas.mdl" );
|
||||
PRECACHE_SOUND( "items/9mmclip1.wav" );
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,18 @@ const char *CBreakable::pSpawnObjects[] =
|
|||
"weapon_satchel", // 19
|
||||
"weapon_snark", // 20
|
||||
"weapon_hornetgun", // 21
|
||||
"weapon_einar1", // 22
|
||||
"ammo_th_sniper", // 23
|
||||
"weapon_th_spanner", // 24
|
||||
"weapon_th_ap9", // 25
|
||||
"ammo_th_ap9", // 26
|
||||
"weapon_th_shovel", // 27
|
||||
"weapon_th_taurus", // 28
|
||||
"ammo_th_taurus", // 29
|
||||
"weapon_th_chaingun", // 30
|
||||
"weapon_th_medkit", // 31
|
||||
"weapon_th_sniper", // 32
|
||||
"ammo_th_sniper", // 33
|
||||
};
|
||||
|
||||
void CBreakable::KeyValue( KeyValueData* pkvd )
|
||||
|
|
158
dlls/game.cpp
158
dlls/game.cpp
|
@ -439,6 +439,84 @@ cvar_t sk_player_leg1 = { "sk_player_leg1","1" };
|
|||
cvar_t sk_player_leg2 = { "sk_player_leg2","1" };
|
||||
cvar_t sk_player_leg3 = { "sk_player_leg3","1" };
|
||||
|
||||
// MONSTERS
|
||||
|
||||
// Baby Kelly
|
||||
cvar_t sk_babykelly_health1 = { "sk_babykelly_health1", "0" };
|
||||
cvar_t sk_babykelly_health2 = { "sk_babykelly_health2", "0" };
|
||||
cvar_t sk_babykelly_health3 = { "sk_babykelly_health3", "0" };
|
||||
|
||||
// Boss
|
||||
cvar_t sk_boss_health1 = { "sk_boss_health1", "0" };
|
||||
cvar_t sk_boss_health2 = { "sk_boss_health2", "0" };
|
||||
cvar_t sk_boss_health3 = { "sk_boss_health3", "0" };
|
||||
|
||||
cvar_t sk_cyberfranklin_health1 = { "sk_cyberfranklin_health1", "0" };
|
||||
cvar_t sk_cyberfranklin_health2 = { "sk_cyberfranklin_health2", "0" };
|
||||
cvar_t sk_cyberfranklin_health3 = { "sk_cyberfranklin_health3", "0" };
|
||||
|
||||
// Houndeye
|
||||
cvar_t sk_houndeye_dmg_bite1 = { "sk_houndeye_dmg_bite1", "0" };
|
||||
cvar_t sk_houndeye_dmg_bite2 = { "sk_houndeye_dmg_bite2", "0" };
|
||||
cvar_t sk_houndeye_dmg_bite3 = { "sk_houndeye_dmg_bite3", "0" };
|
||||
|
||||
// Megasquid
|
||||
cvar_t sk_megasquid_health1 = { "sk_megasquid_health1", "0" };
|
||||
cvar_t sk_megasquid_health2 = { "sk_megasquid_health2", "0" };
|
||||
cvar_t sk_megasquid_health3 = { "sk_megasquid_health3", "0" };
|
||||
|
||||
// Zombie bull
|
||||
cvar_t sk_zombiebull_health1 = { "sk_zombiebull_health1", "0" };
|
||||
cvar_t sk_zombiebull_health2 = { "sk_zombiebull_health2", "0" };
|
||||
cvar_t sk_zombiebull_health3 = { "sk_zombiebull_health3", "0" };
|
||||
|
||||
cvar_t sk_zombiebull_dmg_bite1 = { "sk_zombiebull_dmg_bite1", "0" };
|
||||
cvar_t sk_zombiebull_dmg_bite2 = { "sk_zombiebull_dmg_bite2", "0" };
|
||||
cvar_t sk_zombiebull_dmg_bite3 = { "sk_zombiebull_dmg_bite3", "0" };
|
||||
|
||||
cvar_t sk_zombiebull_dmg_whip1 = { "sk_zombiebull_dmg_whip1", "0" };
|
||||
cvar_t sk_zombiebull_dmg_whip2 = { "sk_zombiebull_dmg_whip2", "0" };
|
||||
cvar_t sk_zombiebull_dmg_whip3 = { "sk_zombiebull_dmg_whip3", "0" };
|
||||
|
||||
// PLAYER WEAPONS
|
||||
|
||||
// Shovel
|
||||
cvar_t sk_plr_shovel1 = { "sk_plr_shovel1", "0" };
|
||||
cvar_t sk_plr_shovel2 = { "sk_plr_shovel2", "0" };
|
||||
cvar_t sk_plr_shovel3 = { "sk_plr_shovel3", "0" };
|
||||
|
||||
// Spanner
|
||||
cvar_t sk_plr_spanner1 = { "sk_plr_spanner1", "0" };
|
||||
cvar_t sk_plr_spanner2 = { "sk_plr_spanner2", "0" };
|
||||
cvar_t sk_plr_spanner3 = { "sk_plr_spanner3", "0" };
|
||||
|
||||
// AP9 Round
|
||||
cvar_t sk_plr_ap9_bullet1 = { "sk_plr_ap9_bullet1", "0" };
|
||||
cvar_t sk_plr_ap9_bullet2 = { "sk_plr_ap9_bullet2", "0" };
|
||||
cvar_t sk_plr_ap9_bullet3 = { "sk_plr_ap9_bullet3", "0" };
|
||||
|
||||
// Taurus Round
|
||||
cvar_t sk_plr_taurus_bullet1 = { "sk_plr_taurus_bullet1", "0" };
|
||||
cvar_t sk_plr_taurus_bullet2 = { "sk_plr_taurus_bullet2", "0" };
|
||||
cvar_t sk_plr_taurus_bullet3 = { "sk_plr_taurus_bullet3", "0" };
|
||||
|
||||
// Sniper Round
|
||||
cvar_t sk_plr_sniper_bullet1 = { "sk_plr_sniper_bullet1", "0" };
|
||||
cvar_t sk_plr_sniper_bullet2 = { "sk_plr_sniper_bullet2", "0" };
|
||||
cvar_t sk_plr_sniper_bullet3 = { "sk_plr_sniper_bullet3", "0" };
|
||||
|
||||
// Flamethrower
|
||||
cvar_t sk_plr_flame1 = { "sk_plr_flame1", "0" };
|
||||
cvar_t sk_plr_flame2 = { "sk_plr_flame2", "0" };
|
||||
cvar_t sk_plr_flame3 = { "sk_plr_flame3", "0" };
|
||||
|
||||
// HEALTH/SUIT CHARGE DISTRIBUTION
|
||||
|
||||
// Medkit
|
||||
cvar_t sk_medkit1 = { "sk_medkit1", "0" };
|
||||
cvar_t sk_medkit2 = { "sk_medkit2", "0" };
|
||||
cvar_t sk_medkit3 = { "sk_medkit3", "0" };
|
||||
|
||||
// END Cvars for Skill Level settings
|
||||
|
||||
// Register your console variables here
|
||||
|
@ -847,6 +925,86 @@ void GameDLLInit( void )
|
|||
CVAR_REGISTER( &sk_player_leg1 );
|
||||
CVAR_REGISTER( &sk_player_leg2 );
|
||||
CVAR_REGISTER( &sk_player_leg3 );
|
||||
|
||||
// MONSTERS
|
||||
|
||||
// Baby Kelly
|
||||
CVAR_REGISTER( &sk_babykelly_health1 );
|
||||
CVAR_REGISTER( &sk_babykelly_health2 );
|
||||
CVAR_REGISTER( &sk_babykelly_health3 );
|
||||
|
||||
// Boss
|
||||
CVAR_REGISTER( &sk_boss_health1 );
|
||||
CVAR_REGISTER( &sk_boss_health2 );
|
||||
CVAR_REGISTER( &sk_boss_health3 );
|
||||
|
||||
// Cyber Franklin
|
||||
CVAR_REGISTER( &sk_cyberfranklin_health1 );
|
||||
CVAR_REGISTER( &sk_cyberfranklin_health2 );
|
||||
CVAR_REGISTER( &sk_cyberfranklin_health3 );
|
||||
|
||||
// Houndeye
|
||||
CVAR_REGISTER( &sk_houndeye_dmg_bite1 );
|
||||
CVAR_REGISTER( &sk_houndeye_dmg_bite2 );
|
||||
CVAR_REGISTER( &sk_houndeye_dmg_bite3 );
|
||||
|
||||
// Megasquid
|
||||
CVAR_REGISTER( &sk_megasquid_health1 );
|
||||
CVAR_REGISTER( &sk_megasquid_health2 );
|
||||
CVAR_REGISTER( &sk_megasquid_health3 );
|
||||
|
||||
// Zombie bull
|
||||
CVAR_REGISTER( &sk_zombiebull_health1 );
|
||||
CVAR_REGISTER( &sk_zombiebull_health2 );
|
||||
CVAR_REGISTER( &sk_zombiebull_health3 );
|
||||
|
||||
CVAR_REGISTER( &sk_zombiebull_dmg_bite1 );
|
||||
CVAR_REGISTER( &sk_zombiebull_dmg_bite2 );
|
||||
CVAR_REGISTER( &sk_zombiebull_dmg_bite3 );
|
||||
|
||||
CVAR_REGISTER( &sk_zombiebull_dmg_whip1 );
|
||||
CVAR_REGISTER( &sk_zombiebull_dmg_whip2 );
|
||||
CVAR_REGISTER( &sk_zombiebull_dmg_whip3 );
|
||||
|
||||
// PLAYER WEAPONS
|
||||
|
||||
// Shovel
|
||||
CVAR_REGISTER( &sk_plr_shovel1 );
|
||||
CVAR_REGISTER( &sk_plr_shovel2 );
|
||||
CVAR_REGISTER( &sk_plr_shovel3 );
|
||||
|
||||
// Spanner
|
||||
CVAR_REGISTER( &sk_plr_spanner1 );
|
||||
CVAR_REGISTER( &sk_plr_spanner2 );
|
||||
CVAR_REGISTER( &sk_plr_spanner3 );
|
||||
|
||||
// AP9 Round
|
||||
CVAR_REGISTER( &sk_plr_ap9_bullet1 );
|
||||
CVAR_REGISTER( &sk_plr_ap9_bullet2 );
|
||||
CVAR_REGISTER( &sk_plr_ap9_bullet3 );
|
||||
|
||||
// Taurus Round
|
||||
CVAR_REGISTER( &sk_plr_taurus_bullet1 );
|
||||
CVAR_REGISTER( &sk_plr_taurus_bullet2 );
|
||||
CVAR_REGISTER( &sk_plr_taurus_bullet3 );
|
||||
|
||||
// Sniper Round
|
||||
CVAR_REGISTER( &sk_plr_sniper_bullet1 );
|
||||
CVAR_REGISTER( &sk_plr_sniper_bullet2 );
|
||||
CVAR_REGISTER( &sk_plr_sniper_bullet3 );
|
||||
|
||||
// Flamethrower
|
||||
CVAR_REGISTER( &sk_plr_flame1 );
|
||||
CVAR_REGISTER( &sk_plr_flame2 );
|
||||
CVAR_REGISTER( &sk_plr_flame3 );
|
||||
|
||||
// HEALTH/SUIT CHARGE DISTRIBUTION
|
||||
|
||||
// Medkit
|
||||
CVAR_REGISTER( &sk_medkit1 );
|
||||
CVAR_REGISTER( &sk_medkit2 );
|
||||
CVAR_REGISTER( &sk_medkit3 );
|
||||
|
||||
// END REGISTER CVARS FOR SKILL LEVEL STUFF
|
||||
|
||||
SERVER_COMMAND( "exec skill.cfg\n" );
|
||||
|
|
|
@ -301,6 +301,53 @@ void CGameRules::RefreshSkillData ( void )
|
|||
gSkillData.plrStomach = GetSkillCvar( "sk_player_stomach" );
|
||||
gSkillData.plrLeg = GetSkillCvar( "sk_player_leg" );
|
||||
gSkillData.plrArm = GetSkillCvar( "sk_player_arm" );
|
||||
|
||||
// MONSTERS
|
||||
|
||||
// Baby kelly
|
||||
gSkillData.babykellyhealth = GetSkillCvar( "sk_babykelly_health" );
|
||||
|
||||
// Boss
|
||||
gSkillData.bossHealth = GetSkillCvar( "sk_boss_health" );
|
||||
|
||||
// Cyber Franklin
|
||||
gSkillData.cyberfranklinHealth = GetSkillCvar( "sk_cyberfranklin_health" );
|
||||
|
||||
// Houndeye
|
||||
gSkillData.houndeyeDmgBite = GetSkillCvar( "sk_houndeye_dmg_bite" );
|
||||
|
||||
// Megasquid
|
||||
gSkillData.megasquidHealth = GetSkillCvar( "sk_megasquid_health" );
|
||||
|
||||
// Zombie bull
|
||||
gSkillData.zombiebullHealth = GetSkillCvar( "sk_zombiebull_health" );
|
||||
gSkillData.zombiebullDmgBite = GetSkillCvar( "sk_zombiebull_dmg_bite" );
|
||||
gSkillData.zombiebullDmgWhip = GetSkillCvar( "sk_zombiebull_dmg_whip" );
|
||||
|
||||
// PLAYER WEAPONS
|
||||
|
||||
// Shovel
|
||||
gSkillData.plrDmgShovel = GetSkillCvar( "sk_plr_shovel" );
|
||||
|
||||
// Spanner
|
||||
gSkillData.plrDmgSpanner = GetSkillCvar( "sk_plr_spanner" );
|
||||
|
||||
// AP9 Round
|
||||
gSkillData.plrDmgAP9 = GetSkillCvar( "sk_plr_ap9_bullet" );
|
||||
|
||||
// Taurus Round
|
||||
gSkillData.plrDmgTaurus = GetSkillCvar( "sk_plr_taurus_bullet" );
|
||||
|
||||
// Sniper Round
|
||||
gSkillData.plrDmgSniper = GetSkillCvar( "sk_plr_sniper_bullet" );
|
||||
|
||||
// Flamethrower
|
||||
gSkillData.plrDmgFlame = GetSkillCvar( "sk_plr_flame" );
|
||||
|
||||
// HEALTH/CHARGE
|
||||
|
||||
// Medkit
|
||||
gSkillData.medkitHeal = GetSkillCvar( "sk_medkit" );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
|
149
dlls/glock.cpp
149
dlls/glock.cpp
|
@ -21,6 +21,13 @@
|
|||
#include "nodes.h"
|
||||
#include "player.h"
|
||||
|
||||
#define GLOCK_MODEL_DEFAULT "models/w_9mmhandgun.mdl"
|
||||
#define GLOCK_MODEL_SILENCER "models/w_silencer.mdl"
|
||||
|
||||
#define SILENCER_GROUP 2
|
||||
#define SILENCER_OFF 0
|
||||
#define SILENCER_ON 1
|
||||
|
||||
enum glock_e
|
||||
{
|
||||
GLOCK_IDLE1 = 0,
|
||||
|
@ -43,7 +50,17 @@ void CGlock::Spawn()
|
|||
pev->classname = MAKE_STRING( "weapon_9mmhandgun" ); // hack to allow for old names
|
||||
Precache();
|
||||
m_iId = WEAPON_GLOCK;
|
||||
SET_MODEL( ENT( pev ), "models/w_9mmhandgun.mdl" );
|
||||
char* szModel = NULL;
|
||||
|
||||
if( pev->body == SILENCER_ON )
|
||||
szModel = GLOCK_MODEL_SILENCER;
|
||||
else
|
||||
szModel = GLOCK_MODEL_DEFAULT;
|
||||
|
||||
SET_MODEL( ENT( pev ), szModel );
|
||||
|
||||
// Always put the silencer on, for now.
|
||||
m_fSilencerOn = TRUE;
|
||||
|
||||
m_iDefaultAmmo = GLOCK_DEFAULT_GIVE;
|
||||
|
||||
|
@ -54,6 +71,7 @@ void CGlock::Precache( void )
|
|||
{
|
||||
PRECACHE_MODEL( "models/v_9mmhandgun.mdl" );
|
||||
PRECACHE_MODEL( "models/w_9mmhandgun.mdl" );
|
||||
PRECACHE_MODEL( "models/w_silencer.mdl" );
|
||||
PRECACHE_MODEL( "models/p_9mmhandgun.mdl" );
|
||||
|
||||
m_iShell = PRECACHE_MODEL( "models/shell.mdl" );// brass shell
|
||||
|
@ -88,18 +106,66 @@ int CGlock::GetItemInfo( ItemInfo *p )
|
|||
|
||||
BOOL CGlock::Deploy()
|
||||
{
|
||||
// pev->body = 1;
|
||||
return DefaultDeploy( "models/v_9mmhandgun.mdl", "models/p_9mmhandgun.mdl", GLOCK_DRAW, "onehanded", /*UseDecrement() ? 1 : 0*/ 0 );
|
||||
#ifdef CLIENT_DLL
|
||||
pev->body = 1;
|
||||
#endif
|
||||
return DefaultDeploy( "models/v_9mmhandgun.mdl", "models/p_9mmhandgun.mdl", GLOCK_DRAW, "onehanded", UseDecrement(), pev->body );
|
||||
}
|
||||
void CGlock::Holster( int skiplocal /*= 0*/ )
|
||||
{
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
SendWeaponAnim( GLOCK_HOLSTER );
|
||||
|
||||
m_fInAttack = 0;
|
||||
}
|
||||
|
||||
BOOL CGlock::ShouldWeaponIdle( void )
|
||||
{
|
||||
return m_fInAttack != 0;
|
||||
}
|
||||
|
||||
void CGlock::SecondaryAttack( void )
|
||||
{
|
||||
GlockFire( 0.1, 0.2, FALSE );
|
||||
if( m_fInAttack != 0 )
|
||||
return;
|
||||
|
||||
if( !m_fSilencerOn )
|
||||
{
|
||||
// Add silencer.
|
||||
m_fInAttack = 1;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0;
|
||||
|
||||
SendWeaponAnim( GLOCK_HOLSTER, 1, SILENCER_OFF );
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay( 2.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove silencer.
|
||||
m_fInAttack = 2;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.4; // 3.3
|
||||
|
||||
SendWeaponAnim( GLOCK_ADD_SILENCER, 1, SILENCER_ON );
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = GetNextAttackDelay( 3.4 );
|
||||
}
|
||||
}
|
||||
|
||||
void CGlock::PrimaryAttack( void )
|
||||
{
|
||||
GlockFire( 0.01, 0.3, TRUE );
|
||||
if( m_fInAttack != 0 )
|
||||
return;
|
||||
|
||||
if( m_fSilencerOn )
|
||||
{
|
||||
GlockFire( 0.01, 0.3, TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
GlockFire( 0.1, 0.2, FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
void CGlock::GlockFire( float flSpread, float flCycleTime, BOOL fUseAutoAim )
|
||||
|
@ -156,7 +222,9 @@ void CGlock::GlockFire( float flSpread, float flCycleTime, BOOL fUseAutoAim )
|
|||
Vector vecDir;
|
||||
vecDir = m_pPlayer->FireBulletsPlayer( 1, vecSrc, vecAiming, Vector( flSpread, flSpread, flSpread ), 8192, BULLET_PLAYER_9MM, 0, 0, m_pPlayer->pev, m_pPlayer->random_seed );
|
||||
|
||||
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), fUseAutoAim ? m_usFireGlock1 : m_usFireGlock2, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, 0, ( m_iClip == 0 ) ? 1 : 0, 0 );
|
||||
int body = m_fSilencerOn ? SILENCER_ON : SILENCER_OFF;
|
||||
|
||||
PLAYBACK_EVENT_FULL( flags, m_pPlayer->edict(), m_usFireGlock1, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, body, 0, ( m_iClip == 0 ) ? 1 : 0, m_fSilencerOn );
|
||||
|
||||
m_flNextPrimaryAttack = m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + flCycleTime;
|
||||
|
||||
|
@ -170,17 +238,21 @@ void CGlock::GlockFire( float flSpread, float flCycleTime, BOOL fUseAutoAim )
|
|||
void CGlock::Reload( void )
|
||||
{
|
||||
if( m_pPlayer->ammo_9mm <= 0 )
|
||||
return;
|
||||
return;
|
||||
|
||||
int body = m_fSilencerOn ? SILENCER_ON : SILENCER_OFF;
|
||||
|
||||
int iResult;
|
||||
|
||||
if( m_iClip == 0 )
|
||||
iResult = DefaultReload( 17, GLOCK_RELOAD, 1.5 );
|
||||
iResult = DefaultReload( GLOCK_MAX_CLIP, GLOCK_RELOAD, 1.5, body );
|
||||
else
|
||||
iResult = DefaultReload( 17, GLOCK_RELOAD_NOT_EMPTY, 1.5 );
|
||||
iResult = DefaultReload( GLOCK_MAX_CLIP, GLOCK_RELOAD_NOT_EMPTY, 1.5, body );
|
||||
|
||||
if( iResult )
|
||||
{
|
||||
m_fInAttack = 0;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );
|
||||
}
|
||||
}
|
||||
|
@ -194,28 +266,51 @@ void CGlock::WeaponIdle( void )
|
|||
if( m_flTimeWeaponIdle > UTIL_WeaponTimeBase() )
|
||||
return;
|
||||
|
||||
// only idle if the slid isn't back
|
||||
if( m_iClip != 0 )
|
||||
if( m_fInAttack != 0 )
|
||||
{
|
||||
int iAnim;
|
||||
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0.0, 1.0 );
|
||||
if( m_fInAttack == 1 )
|
||||
{
|
||||
m_fSilencerOn = TRUE;
|
||||
}
|
||||
else if( m_fInAttack == 2 )
|
||||
{
|
||||
m_fSilencerOn = FALSE;
|
||||
}
|
||||
|
||||
if( flRand <= 0.3 + 0 * 0.75 )
|
||||
int body = m_fSilencerOn ? SILENCER_ON : SILENCER_OFF;
|
||||
|
||||
SendWeaponAnim( GLOCK_DRAW, UseDecrement(), body );
|
||||
|
||||
m_fInAttack = 0;
|
||||
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// only idle if the slid isn't back
|
||||
if( m_iClip != 0 )
|
||||
{
|
||||
iAnim = GLOCK_IDLE3;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 49.0 / 16;
|
||||
int iAnim;
|
||||
float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0.0, 1.0 );
|
||||
|
||||
if( flRand <= 0.3 + 0 * 0.75 )
|
||||
{
|
||||
iAnim = GLOCK_IDLE3;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 49.0 / 16;
|
||||
}
|
||||
else if( flRand <= 0.6 + 0 * 0.875 )
|
||||
{
|
||||
iAnim = GLOCK_IDLE1;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 60.0 / 16.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = GLOCK_IDLE2;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 40.0 / 16.0;
|
||||
}
|
||||
|
||||
SendWeaponAnim( iAnim, 1, m_fSilencerOn ? 1 : 0 );
|
||||
}
|
||||
else if( flRand <= 0.6 + 0 * 0.875 )
|
||||
{
|
||||
iAnim = GLOCK_IDLE1;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 60.0 / 16.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iAnim = GLOCK_IDLE2;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 40.0 / 16.0;
|
||||
}
|
||||
SendWeaponAnim( iAnim, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ void CHandGrenade::Spawn()
|
|||
{
|
||||
Precache();
|
||||
m_iId = WEAPON_HANDGRENADE;
|
||||
SET_MODEL( ENT( pev ), "models/w_grenade.mdl" );
|
||||
SET_MODEL( ENT( pev ), "models/w_tnt.mdl" );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
pev->dmg = gSkillData.plrDmgHandGrenade;
|
||||
|
@ -53,9 +53,9 @@ void CHandGrenade::Spawn()
|
|||
|
||||
void CHandGrenade::Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/w_grenade.mdl" );
|
||||
PRECACHE_MODEL( "models/v_grenade.mdl" );
|
||||
PRECACHE_MODEL( "models/p_grenade.mdl" );
|
||||
PRECACHE_MODEL( "models/w_tnt.mdl" );
|
||||
PRECACHE_MODEL( "models/v_tnt.mdl" );
|
||||
PRECACHE_MODEL( "models/p_tnt.mdl" );
|
||||
}
|
||||
|
||||
int CHandGrenade::GetItemInfo( ItemInfo *p )
|
||||
|
@ -78,7 +78,7 @@ int CHandGrenade::GetItemInfo( ItemInfo *p )
|
|||
BOOL CHandGrenade::Deploy()
|
||||
{
|
||||
m_flReleaseThrow = -1;
|
||||
return DefaultDeploy( "models/v_grenade.mdl", "models/p_grenade.mdl", HANDGRENADE_DRAW, "crowbar" );
|
||||
return DefaultDeploy( "models/v_tnt.mdl", "models/p_tnt.mdl", HANDGRENADE_DRAW, "crowbar" );
|
||||
}
|
||||
|
||||
BOOL CHandGrenade::CanHolster( void )
|
||||
|
@ -150,7 +150,7 @@ void CHandGrenade::WeaponIdle( void )
|
|||
if( time < 0 )
|
||||
time = 0;
|
||||
|
||||
CGrenade::ShootTimed( m_pPlayer->pev, vecSrc, vecThrow, time );
|
||||
CTnt::ShootTimed( m_pPlayer->pev, vecSrc, vecThrow, time );
|
||||
|
||||
if( flVel < 500 )
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "monsters.h"
|
||||
#include "schedule.h"
|
||||
#include "game.h"
|
||||
#include "headcrab.h"
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
|
@ -70,43 +71,6 @@ Schedule_t slHCRangeAttack1Fast[] =
|
|||
},
|
||||
};
|
||||
|
||||
class CHeadCrab : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void RunTask ( Task_t *pTask );
|
||||
void StartTask ( Task_t *pTask );
|
||||
void SetYawSpeed ( void );
|
||||
void EXPORT LeapTouch ( CBaseEntity *pOther );
|
||||
Vector Center( void );
|
||||
Vector BodyTarget( const Vector &posSrc );
|
||||
void PainSound( void );
|
||||
void DeathSound( void );
|
||||
void IdleSound( void );
|
||||
void AlertSound( void );
|
||||
void PrescheduleThink( void );
|
||||
int Classify ( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
BOOL CheckRangeAttack1 ( float flDot, float flDist );
|
||||
BOOL CheckRangeAttack2 ( float flDot, float flDist );
|
||||
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
|
||||
|
||||
virtual float GetDamageAmount( void ) { return gSkillData.headcrabDmgBite; }
|
||||
virtual int GetVoicePitch( void ) { return 100; }
|
||||
virtual float GetSoundVolue( void ) { return 1.0; }
|
||||
Schedule_t* GetScheduleOfType ( int Type );
|
||||
|
||||
CUSTOM_SCHEDULES
|
||||
|
||||
static const char *pIdleSounds[];
|
||||
static const char *pAlertSounds[];
|
||||
static const char *pPainSounds[];
|
||||
static const char *pAttackSounds[];
|
||||
static const char *pDeathSounds[];
|
||||
static const char *pBiteSounds[];
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_headcrab, CHeadCrab )
|
||||
|
||||
DEFINE_CUSTOM_SCHEDULES( CHeadCrab )
|
||||
|
@ -260,9 +224,7 @@ void CHeadCrab::HandleAnimEvent( MonsterEvent_t *pEvent )
|
|||
vecJumpDir = Vector( gpGlobals->v_forward.x, gpGlobals->v_forward.y, gpGlobals->v_up.z ) * 350;
|
||||
}
|
||||
|
||||
int iSound = RANDOM_LONG(0,2);
|
||||
if( iSound != 0 )
|
||||
EMIT_SOUND_DYN( edict(), CHAN_VOICE, pAttackSounds[iSound], GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch() );
|
||||
AttackSound();
|
||||
|
||||
pev->velocity = vecJumpDir;
|
||||
m_flNextAttack = gpGlobals->time + 2;
|
||||
|
@ -286,7 +248,7 @@ void CHeadCrab::Spawn()
|
|||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_GREEN;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->effects = 0;
|
||||
pev->health = gSkillData.headcrabHealth;
|
||||
pev->view_ofs = Vector( 0, 0, 20 );// position of the eyes relative to monster's origin.
|
||||
|
@ -467,6 +429,16 @@ void CHeadCrab::DeathSound( void )
|
|||
EMIT_SOUND_DYN( edict(), CHAN_VOICE, RANDOM_SOUND_ARRAY( pDeathSounds ), GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch() );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// AttackSound
|
||||
//=========================================================
|
||||
void CHeadCrab::AttackSound( void )
|
||||
{
|
||||
int iSound = RANDOM_LONG(0, 2);
|
||||
if( iSound != 0 )
|
||||
EMIT_SOUND_DYN( edict(), CHAN_VOICE, pAttackSounds[iSound], GetSoundVolue(), ATTN_IDLE, 0, GetVoicePitch() );
|
||||
}
|
||||
|
||||
Schedule_t *CHeadCrab::GetScheduleOfType( int Type )
|
||||
{
|
||||
switch( Type )
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/***
|
||||
*
|
||||
* 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 HEADCRAB_H
|
||||
#define HEADCRAB_H
|
||||
|
||||
class CHeadCrab : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void RunTask ( Task_t *pTask );
|
||||
void StartTask ( Task_t *pTask );
|
||||
void SetYawSpeed ( void );
|
||||
void EXPORT LeapTouch ( CBaseEntity *pOther );
|
||||
Vector Center( void );
|
||||
Vector BodyTarget( const Vector &posSrc );
|
||||
virtual void PainSound( void );
|
||||
virtual void DeathSound( void );
|
||||
virtual void IdleSound( void );
|
||||
virtual void AlertSound( void );
|
||||
virtual void AttackSound( void );
|
||||
void PrescheduleThink( void );
|
||||
int Classify ( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
BOOL CheckRangeAttack1 ( float flDot, float flDist );
|
||||
BOOL CheckRangeAttack2 ( float flDot, float flDist );
|
||||
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
|
||||
|
||||
virtual float GetDamageAmount( void ) { return gSkillData.headcrabDmgBite; }
|
||||
virtual int GetVoicePitch( void ) { return 100; }
|
||||
virtual float GetSoundVolue( void ) { return 1.0; }
|
||||
Schedule_t* GetScheduleOfType ( int Type );
|
||||
|
||||
CUSTOM_SCHEDULES;
|
||||
|
||||
static const char *pIdleSounds[];
|
||||
static const char *pAlertSounds[];
|
||||
static const char *pPainSounds[];
|
||||
static const char *pAttackSounds[];
|
||||
static const char *pDeathSounds[];
|
||||
static const char *pBiteSounds[];
|
||||
};
|
||||
#endif // HEADCRAB_H
|
226
dlls/hgrunt.cpp
226
dlls/hgrunt.cpp
|
@ -40,6 +40,12 @@
|
|||
#include "soundent.h"
|
||||
#include "effects.h"
|
||||
#include "customentity.h"
|
||||
#include "hgrunt.h"
|
||||
|
||||
//
|
||||
// Spawn flags
|
||||
//
|
||||
#define SF_HGRUNT_ZSOLDIER 64
|
||||
|
||||
int g_fGruntQuestion; // true if an idle grunt asked a question. Cleared when someone answers.
|
||||
|
||||
|
@ -71,6 +77,9 @@ extern DLL_GLOBAL int g_iSkillLevel;
|
|||
#define GUN_MP5 0
|
||||
#define GUN_SHOTGUN 1
|
||||
#define GUN_NONE 2
|
||||
#define PARACHUTE_GROUP 3
|
||||
#define PARACHUTE_OFF 0
|
||||
#define PARACHUTE_ON 1
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
|
@ -119,73 +128,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[] =
|
||||
|
@ -202,6 +144,7 @@ TYPEDESCRIPTION CHGrunt::m_SaveData[] =
|
|||
//DEFINE_FIELD( CShotgun, m_iBrassShell, FIELD_INTEGER ),
|
||||
//DEFINE_FIELD( CShotgun, m_iShotgunShell, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CHGrunt, m_iSentence, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( CHGrunt, m_iGruntFlags, FIELD_INTEGER ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CHGrunt, CSquadMonster )
|
||||
|
@ -332,6 +275,10 @@ int CHGrunt::ISoundMask( void )
|
|||
//=========================================================
|
||||
BOOL CHGrunt::FOkToSpeak( void )
|
||||
{
|
||||
// Zombie soldiers do not speak.
|
||||
if( IsZombieSoldier() )
|
||||
return FALSE;
|
||||
|
||||
// if someone else is talking, don't speak
|
||||
if( gpGlobals->time <= CTalkMonster::g_talkWaitTime )
|
||||
return FALSE;
|
||||
|
@ -632,6 +579,19 @@ int CHGrunt::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float
|
|||
return CSquadMonster::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType );
|
||||
}
|
||||
|
||||
void CHGrunt::Killed( entvars_t *pevAttacker, int iGib )
|
||||
{
|
||||
//
|
||||
// If a grunt is killed while using a parachute, update
|
||||
// bodygroup to make it invisible.
|
||||
//
|
||||
if( GetBodygroup( PARACHUTE_GROUP ) == PARACHUTE_ON )
|
||||
{
|
||||
SetBodygroup( PARACHUTE_GROUP, PARACHUTE_OFF );
|
||||
}
|
||||
|
||||
CSquadMonster::Killed( pevAttacker, iGib );
|
||||
}
|
||||
//=========================================================
|
||||
// SetYawSpeed - allows each sequence to have a different
|
||||
// turn rate associated with it.
|
||||
|
@ -741,6 +701,9 @@ void CHGrunt::CheckAmmo( void )
|
|||
//=========================================================
|
||||
int CHGrunt::Classify( void )
|
||||
{
|
||||
if( IsZombieSoldier() )
|
||||
return CLASS_ALIEN_MONSTER;
|
||||
|
||||
return CLASS_HUMAN_MILITARY;
|
||||
}
|
||||
|
||||
|
@ -972,7 +935,33 @@ void CHGrunt::Spawn()
|
|||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL( ENT( pev ), "models/hgrunt.mdl" );
|
||||
m_iGruntFlags = 0;
|
||||
|
||||
// Check if this is a zombie soldier.
|
||||
if( pev->spawnflags & SF_HGRUNT_ZSOLDIER )
|
||||
{
|
||||
m_iGruntFlags |= GF_ZSOLDIER;
|
||||
}
|
||||
|
||||
char* szModel = (char*)STRING( pev->model );
|
||||
|
||||
// If this is a zombie soldier with a regular grunt model,
|
||||
// switch to appropriate model.
|
||||
if( IsZombieSoldier() && !FStrEq( szModel, "models/zgrunt.mdl" ) )
|
||||
{
|
||||
szModel = "models/zgrunt.mdl";
|
||||
pev->model = ALLOC_STRING( szModel );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pick regular grunt model.
|
||||
szModel = "models/hgrunt.mdl";
|
||||
pev->model = ALLOC_STRING( szModel );
|
||||
}
|
||||
|
||||
// Set new model.
|
||||
SET_MODEL( ENT( pev ), (char*)STRING( pev->model ) );
|
||||
|
||||
UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
|
@ -1038,6 +1027,7 @@ void CHGrunt::Spawn()
|
|||
void CHGrunt::Precache()
|
||||
{
|
||||
PRECACHE_MODEL( "models/hgrunt.mdl" );
|
||||
PRECACHE_MODEL( "models/zgrunt.mdl" );
|
||||
|
||||
PRECACHE_SOUND( "hgrunt/gr_mgun1.wav" );
|
||||
PRECACHE_SOUND( "hgrunt/gr_mgun2.wav" );
|
||||
|
@ -1203,6 +1193,11 @@ void CHGrunt::DeathSound( void )
|
|||
}
|
||||
}
|
||||
|
||||
BOOL CHGrunt::IsZombieSoldier( void ) const
|
||||
{
|
||||
return ( m_iGruntFlags & GF_ZSOLDIER );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// AI Schedules Specific to this monster
|
||||
//=========================================================
|
||||
|
@ -1910,6 +1905,17 @@ void CHGrunt::SetActivity( Activity NewActivity )
|
|||
}
|
||||
iSequence = LookupActivity( NewActivity );
|
||||
break;
|
||||
case ACT_LAND:
|
||||
//
|
||||
// If a grunt landed using a parachute, update
|
||||
// bodygroup to make it invisible.
|
||||
//
|
||||
if( GetBodygroup( PARACHUTE_GROUP ) == PARACHUTE_ON )
|
||||
{
|
||||
SetBodygroup( PARACHUTE_GROUP, PARACHUTE_OFF );
|
||||
}
|
||||
iSequence = LookupActivity( NewActivity );
|
||||
break;
|
||||
default:
|
||||
iSequence = LookupActivity( NewActivity );
|
||||
break;
|
||||
|
@ -2212,13 +2218,31 @@ Schedule_t *CHGrunt::GetScheduleOfType( int Type )
|
|||
}
|
||||
else
|
||||
{
|
||||
if( RANDOM_LONG( 0, 1 ) )
|
||||
// Zombie soldiers cannot use grenades.
|
||||
if( IsZombieSoldier() )
|
||||
{
|
||||
return &slGruntTakeCover[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return &slGruntGrenadeCover[0];
|
||||
// Regular cover.
|
||||
if( RANDOM_LONG( 0, 1 ) )
|
||||
{
|
||||
return &slGruntTakeCover[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !FClassnameIs( pev,"monster_th_cyberfranklin" ) )
|
||||
{
|
||||
// Regular grenade cover.
|
||||
return &slGruntGrenadeCover[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Prevent Cyber franklin from dropping grenades down.
|
||||
return &slGruntTakeCover[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2343,15 +2367,7 @@ Schedule_t *CHGrunt::GetScheduleOfType( int Type )
|
|||
// CHGruntRepel - when triggered, spawns a monster_human_grunt
|
||||
// repelling down a line.
|
||||
//=========================================================
|
||||
|
||||
class CHGruntRepel : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void EXPORT RepelUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
|
||||
int m_iSpriteTexture; // Don't save, precache
|
||||
};
|
||||
#define SF_REPEL_PARACHUTE 32
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_grunt_repel, CHGruntRepel )
|
||||
|
||||
|
@ -2386,6 +2402,23 @@ void CHGruntRepel::RepelUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_
|
|||
// UNDONE: position?
|
||||
pGrunt->m_vecLastPosition = tr.vecEndPos;
|
||||
|
||||
//
|
||||
// Fix trigger condition targets.
|
||||
//
|
||||
pGrunt->m_iszTriggerTarget = m_iszTriggerTarget;
|
||||
pGrunt->m_iTriggerCondition = m_iTriggerCondition;
|
||||
|
||||
// If this is a parachuted grunt, set parachute
|
||||
// bodygroup visible.
|
||||
if( pev->spawnflags & SF_REPEL_PARACHUTE )
|
||||
{
|
||||
pGrunt->SetBodygroup( PARACHUTE_GROUP, PARACHUTE_ON );
|
||||
|
||||
// Do not spawn beam. Return.
|
||||
UTIL_Remove( this );
|
||||
return;
|
||||
}
|
||||
|
||||
CBeam *pBeam = CBeam::BeamCreate( "sprites/rope.spr", 10 );
|
||||
pBeam->PointEntInit( pev->origin + Vector( 0, 0, 112 ), pGrunt->entindex() );
|
||||
pBeam->SetFlags( BEAM_FSOLID );
|
||||
|
@ -2399,18 +2432,6 @@ void CHGruntRepel::RepelUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_
|
|||
//=========================================================
|
||||
// DEAD HGRUNT PROP
|
||||
//=========================================================
|
||||
class CDeadHGrunt : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
int Classify( void ) { return CLASS_HUMAN_MILITARY; }
|
||||
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
|
||||
int m_iPose;// which sequence to display -- temporary, don't need to save
|
||||
static char *m_szPoses[3];
|
||||
};
|
||||
|
||||
char *CDeadHGrunt::m_szPoses[] = { "deadstomach", "deadside", "deadsitting" };
|
||||
|
||||
void CDeadHGrunt::KeyValue( KeyValueData *pkvd )
|
||||
|
@ -2432,7 +2453,28 @@ LINK_ENTITY_TO_CLASS( monster_hgrunt_dead, CDeadHGrunt )
|
|||
void CDeadHGrunt::Spawn( void )
|
||||
{
|
||||
PRECACHE_MODEL( "models/hgrunt.mdl" );
|
||||
SET_MODEL( ENT( pev ), "models/hgrunt.mdl" );
|
||||
PRECACHE_MODEL( "models/zgrunt.mdl" );
|
||||
|
||||
char* szModel = (char*)STRING( pev->model );
|
||||
|
||||
//
|
||||
// Pick regular grunt model.
|
||||
//
|
||||
if( !szModel || !*szModel )
|
||||
{
|
||||
szModel = "models/hgrunt.mdl";
|
||||
pev->model = ALLOC_STRING( szModel );
|
||||
}
|
||||
// If this is a zombie soldier with a regular grunt model,
|
||||
// switch to appropriate model.
|
||||
else if( ( pev->spawnflags & SF_HGRUNT_ZSOLDIER ) && !FStrEq( szModel, "models/zgrunt.mdl" ) )
|
||||
{
|
||||
szModel = "models/zgrunt.mdl";
|
||||
pev->model = ALLOC_STRING( szModel );
|
||||
}
|
||||
|
||||
// Set new model.
|
||||
SET_MODEL( ENT( pev ), (char*)STRING( pev->model ) )
|
||||
|
||||
pev->effects = 0;
|
||||
pev->yaw_speed = 8;
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/***
|
||||
*
|
||||
* 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
|
||||
|
||||
//
|
||||
// Special Grunt flags
|
||||
//
|
||||
#define GF_ZSOLDIER 1
|
||||
|
||||
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 );
|
||||
void Killed(entvars_t *pevAttacker, int iGib);
|
||||
|
||||
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[];
|
||||
|
||||
BOOL IsZombieSoldier() const;
|
||||
|
||||
int m_iGruntFlags;
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// CHGruntRepel - when triggered, spawns a monster_human_grunt
|
||||
// repelling down a line.
|
||||
//=========================================================
|
||||
class CHGruntRepel : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
void EXPORT RepelUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
|
||||
int m_iSpriteTexture; // Don't save, precache
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// DEAD HGRUNT PROP
|
||||
//=========================================================
|
||||
class CDeadHGrunt : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
int Classify(void) { return CLASS_HUMAN_MILITARY; }
|
||||
|
||||
void KeyValue(KeyValueData *pkvd);
|
||||
|
||||
int m_iPose;// which sequence to display -- temporary, don't need to save
|
||||
static char *m_szPoses[3];
|
||||
};
|
||||
|
||||
#endif // HGRUNT_H
|
|
@ -223,18 +223,18 @@ old colors
|
|||
switch( m_iHornetType )
|
||||
{
|
||||
case HORNET_TYPE_RED:
|
||||
WRITE_BYTE( 179 ); // r, g, b
|
||||
WRITE_BYTE( 39 ); // r, g, b
|
||||
WRITE_BYTE( 14 ); // r, g, b
|
||||
WRITE_BYTE( 255 ); // r, g, b
|
||||
WRITE_BYTE( 0 ); // r, g, b
|
||||
WRITE_BYTE( 255 ); // r, g, b
|
||||
break;
|
||||
case HORNET_TYPE_ORANGE:
|
||||
WRITE_BYTE( 255 ); // r, g, b
|
||||
WRITE_BYTE( 128 ); // r, g, b
|
||||
WRITE_BYTE( 0 ); // r, g, b
|
||||
WRITE_BYTE( 255 ); // r, g, b
|
||||
WRITE_BYTE( 255 ); // r, g, b
|
||||
break;
|
||||
}
|
||||
|
||||
WRITE_BYTE( 128 ); // brightness
|
||||
WRITE_BYTE( 0 ); // brightness
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ extern CGraph WorldGraph;
|
|||
// houndeye does 20 points of damage spread over a sphere 384 units in diameter, and each additional
|
||||
// squad member increases the BASE damage by 110%, per the spec.
|
||||
#define HOUNDEYE_MAX_SQUAD_SIZE 4
|
||||
#define HOUNDEYE_MAX_ATTACK_RADIUS 384
|
||||
#define HOUNDEYE_MAX_ATTACK_RADIUS 96
|
||||
#define HOUNDEYE_SQUAD_BONUS (float)1.1
|
||||
|
||||
#define HOUNDEYE_EYE_FRAMES 4 // how many different switchable maps for the eye
|
||||
|
@ -277,7 +277,23 @@ void CHoundeye::HandleAnimEvent( MonsterEvent_t *pEvent )
|
|||
WarnSound();
|
||||
break;
|
||||
case HOUND_AE_STARTATTACK:
|
||||
WarmUpSound();
|
||||
{
|
||||
// SOUND HERE!
|
||||
CBaseEntity *pHurt = CheckTraceHullAttack( 80, gSkillData.houndeyeDmgBite, DMG_SLASH );
|
||||
|
||||
if( pHurt )
|
||||
{
|
||||
if( pHurt->pev->flags & ( FL_CLIENT | FL_MONSTER ) )
|
||||
{
|
||||
pHurt->pev->punchangle.x = 2;
|
||||
}
|
||||
|
||||
pHurt->pev->velocity = pHurt->pev->velocity - gpGlobals->v_forward * 16;
|
||||
pHurt->pev->velocity = pHurt->pev->velocity + gpGlobals->v_up * 8;
|
||||
}
|
||||
|
||||
WarmUpSound();
|
||||
}
|
||||
break;
|
||||
case HOUND_AE_HOPBACK:
|
||||
{
|
||||
|
@ -290,8 +306,6 @@ void CHoundeye::HandleAnimEvent( MonsterEvent_t *pEvent )
|
|||
break;
|
||||
}
|
||||
case HOUND_AE_THUMP:
|
||||
// emit the shockwaves
|
||||
SonicAttack();
|
||||
break;
|
||||
case HOUND_AE_ANGERSOUND1:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "houndeye/he_pain3.wav", 1, ATTN_NORM );
|
||||
|
@ -323,7 +337,7 @@ void CHoundeye::Spawn()
|
|||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_YELLOW;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->effects = 0;
|
||||
pev->health = gSkillData.houndeyeHealth;
|
||||
pev->yaw_speed = 5;//!!! should we put this in the monster's changeanim function since turn rates may vary with state/anim?
|
||||
|
@ -365,6 +379,7 @@ void CHoundeye::Precache()
|
|||
PRECACHE_SOUND( "houndeye/he_pain5.wav" );
|
||||
|
||||
PRECACHE_SOUND( "houndeye/he_attack1.wav" );
|
||||
PRECACHE_SOUND( "houndeye/he_attack2.wav" );
|
||||
PRECACHE_SOUND( "houndeye/he_attack3.wav" );
|
||||
|
||||
PRECACHE_SOUND( "houndeye/he_blast1.wav" );
|
||||
|
@ -398,7 +413,7 @@ void CHoundeye::IdleSound( void )
|
|||
//=========================================================
|
||||
void CHoundeye::WarmUpSound( void )
|
||||
{
|
||||
switch( RANDOM_LONG( 0, 1 ) )
|
||||
switch( RANDOM_LONG( 0, 2 ) )
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_WEAPON, "houndeye/he_attack1.wav", 0.7, ATTN_NORM );
|
||||
|
@ -406,6 +421,9 @@ void CHoundeye::WarmUpSound( void )
|
|||
case 1:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_WEAPON, "houndeye/he_attack3.wav", 0.7, ATTN_NORM );
|
||||
break;
|
||||
case 2:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_WEAPON, "houndeye/he_attack2.wav", 0.7, ATTN_NORM );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -471,7 +471,7 @@ void CIchthyosaur::Spawn()
|
|||
|
||||
pev->solid = SOLID_BBOX;
|
||||
pev->movetype = MOVETYPE_FLY;
|
||||
m_bloodColor = BLOOD_COLOR_GREEN;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->health = gSkillData.ichthyosaurHealth;
|
||||
pev->view_ofs = Vector( 0, 0, 16 );
|
||||
m_flFieldOfView = VIEW_FIELD_WIDE;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "effects.h"
|
||||
#include "weapons.h"
|
||||
#include "soundent.h"
|
||||
#include "islave.h"
|
||||
|
||||
extern DLL_GLOBAL int g_iSkillLevel;
|
||||
|
||||
|
@ -39,61 +40,6 @@ extern DLL_GLOBAL int g_iSkillLevel;
|
|||
|
||||
#define ISLAVE_MAX_BEAMS 8
|
||||
|
||||
class CISlave : public CSquadMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void SetYawSpeed( void );
|
||||
int ISoundMask( void );
|
||||
int Classify( void );
|
||||
int IRelationship( CBaseEntity *pTarget );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
BOOL CheckRangeAttack1( float flDot, float flDist );
|
||||
BOOL CheckRangeAttack2( float flDot, float flDist );
|
||||
void CallForHelp( char *szClassname, float flDist, EHANDLE hEnemy, Vector &vecLocation );
|
||||
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 );
|
||||
|
||||
void DeathSound( void );
|
||||
void PainSound( void );
|
||||
void AlertSound( void );
|
||||
void IdleSound( void );
|
||||
|
||||
void Killed( entvars_t *pevAttacker, int iGib );
|
||||
|
||||
void StartTask( Task_t *pTask );
|
||||
Schedule_t *GetSchedule( void );
|
||||
Schedule_t *GetScheduleOfType( int Type );
|
||||
CUSTOM_SCHEDULES
|
||||
|
||||
int Save( CSave &save );
|
||||
int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
void ClearBeams();
|
||||
void ArmBeam( int side );
|
||||
void WackBeam( int side, CBaseEntity *pEntity );
|
||||
void ZapBeam( int side );
|
||||
void BeamGlow( void );
|
||||
|
||||
int m_iBravery;
|
||||
|
||||
CBeam *m_pBeam[ISLAVE_MAX_BEAMS];
|
||||
|
||||
int m_iBeams;
|
||||
float m_flNextAttack;
|
||||
|
||||
int m_voicePitch;
|
||||
|
||||
EHANDLE m_hDead;
|
||||
|
||||
static const char *pAttackHitSounds[];
|
||||
static const char *pAttackMissSounds[];
|
||||
static const char *pPainSounds[];
|
||||
static const char *pDeathSounds[];
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_alien_slave, CISlave )
|
||||
LINK_ENTITY_TO_CLASS( monster_vortigaunt, CISlave )
|
||||
|
||||
|
@ -144,7 +90,7 @@ const char *CISlave::pDeathSounds[] =
|
|||
//=========================================================
|
||||
int CISlave::Classify( void )
|
||||
{
|
||||
return CLASS_ALIEN_MILITARY;
|
||||
return CLASS_SKELETON;
|
||||
}
|
||||
|
||||
int CISlave::IRelationship( CBaseEntity *pTarget )
|
||||
|
@ -512,7 +458,7 @@ void CISlave::Spawn()
|
|||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_GREEN;
|
||||
m_bloodColor = DONT_BLEED;
|
||||
pev->effects = 0;
|
||||
pev->health = gSkillData.slaveHealth;
|
||||
pev->view_ofs = Vector( 0, 0, 64 );// position of the eyes relative to monster's origin.
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/***
|
||||
*
|
||||
* 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 ISLAVE_H
|
||||
#define ISLAVE_H
|
||||
|
||||
#define ISLAVE_MAX_BEAMS 8
|
||||
|
||||
class CISlave : public CSquadMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void SetYawSpeed( void );
|
||||
int ISoundMask( void );
|
||||
int Classify ( void );
|
||||
int IRelationship( CBaseEntity *pTarget );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
BOOL CheckRangeAttack1 ( float flDot, float flDist );
|
||||
BOOL CheckRangeAttack2 ( float flDot, float flDist );
|
||||
void CallForHelp( char *szClassname, float flDist, EHANDLE hEnemy, Vector &vecLocation );
|
||||
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);
|
||||
|
||||
void DeathSound( void );
|
||||
void PainSound( void );
|
||||
void AlertSound( void );
|
||||
void IdleSound( void );
|
||||
|
||||
void Killed( entvars_t *pevAttacker, int iGib );
|
||||
BOOL ShouldGibMonster(int iGib) { return FALSE; }
|
||||
|
||||
void StartTask ( Task_t *pTask );
|
||||
Schedule_t *GetSchedule( void );
|
||||
Schedule_t *GetScheduleOfType ( int Type );
|
||||
CUSTOM_SCHEDULES;
|
||||
|
||||
int Save( CSave &save );
|
||||
int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
void ClearBeams( );
|
||||
void ArmBeam( int side );
|
||||
void WackBeam( int side, CBaseEntity *pEntity );
|
||||
void ZapBeam( int side );
|
||||
void BeamGlow( void );
|
||||
|
||||
int m_iBravery;
|
||||
|
||||
CBeam *m_pBeam[ISLAVE_MAX_BEAMS];
|
||||
|
||||
int m_iBeams;
|
||||
float m_flNextAttack;
|
||||
|
||||
int m_voicePitch;
|
||||
|
||||
EHANDLE m_hDead;
|
||||
|
||||
static const char *pAttackHitSounds[];
|
||||
static const char *pAttackMissSounds[];
|
||||
static const char *pPainSounds[];
|
||||
static const char *pDeathSounds[];
|
||||
};
|
||||
#endif // ISLAVE_H
|
|
@ -184,14 +184,6 @@ class CItemSuit : public CItem
|
|||
}
|
||||
BOOL MyTouch( CBasePlayer *pPlayer )
|
||||
{
|
||||
if( pPlayer->pev->weapons & ( 1<<WEAPON_SUIT ) )
|
||||
return FALSE;
|
||||
|
||||
if( pev->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 +206,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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "saverestore.h"
|
||||
#include "barney.h"
|
||||
|
||||
// Monstermaker spawnflags
|
||||
#define SF_MONSTERMAKER_START_ON 1 // start active ( if has targetname )
|
||||
|
@ -214,6 +215,18 @@ void CMonsterMaker::MakeMonster( void )
|
|||
if( pev->spawnflags & SF_MONSTERMAKER_MONSTERCLIP )
|
||||
SetBits( pevCreate->spawnflags, SF_MONSTER_HITMONSTERCLIP );
|
||||
|
||||
// Override monster blood color.
|
||||
if( pev->spawnflags & SF_MONSTER_REDBLOOD )
|
||||
SetBits( pevCreate->spawnflags, SF_MONSTER_REDBLOOD );
|
||||
|
||||
// Override monster relationship.
|
||||
if( pev->spawnflags & SF_MONSTER_ZOMBIECOP )
|
||||
SetBits( pevCreate->spawnflags, SF_MONSTER_ZOMBIECOP );
|
||||
|
||||
// Override monster framerate.
|
||||
if( pev->spawnflags & SF_MONSTER_FASTZOMBIEMODE )
|
||||
SetBits( pevCreate->spawnflags, SF_MONSTER_FASTZOMBIEMODE );
|
||||
|
||||
DispatchSpawn( ENT( pevCreate ) );
|
||||
pevCreate->owner = edict();
|
||||
|
||||
|
@ -223,6 +236,10 @@ void CMonsterMaker::MakeMonster( void )
|
|||
pevCreate->targetname = pev->netname;
|
||||
}
|
||||
|
||||
CBarney* pBarney = (CBarney*)CBaseEntity::Instance( pevCreate );
|
||||
if( pBarney )
|
||||
pBarney->FixupBarneySkin( ( pev->spawnflags & SF_MONSTER_ZOMBIECOP ) ? TRUE : FALSE );
|
||||
|
||||
m_cLiveChildren++;// count this monster
|
||||
m_cNumMonsters--;
|
||||
|
||||
|
|
|
@ -2015,6 +2015,9 @@ void CBaseMonster::MonsterInit( void )
|
|||
// set eye position
|
||||
SetEyePosition();
|
||||
|
||||
if( pev->spawnflags & SF_MONSTER_REDBLOOD )
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
|
||||
SetThink( &CBaseMonster::MonsterInitThink );
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
SetUse( &CBaseMonster::MonsterUse );
|
||||
|
@ -2164,22 +2167,23 @@ int CBaseMonster::TaskIsRunning( void )
|
|||
//=========================================================
|
||||
int CBaseMonster::IRelationship( CBaseEntity *pTarget )
|
||||
{
|
||||
static int iEnemy[14][14] =
|
||||
{ // NONE MACH PLYR HPASS HMIL AMIL APASS AMONST APREY APRED INSECT PLRALY PBWPN ABWPN
|
||||
/*NONE*/ { R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO, R_NO, R_NO },
|
||||
/*MACHINE*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_DL, R_DL, R_DL },
|
||||
/*PLAYER*/ { R_NO ,R_DL ,R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO, R_DL, R_DL },
|
||||
/*HUMANPASSIVE*/{ R_NO ,R_NO ,R_AL ,R_AL ,R_HT ,R_FR ,R_NO ,R_HT ,R_DL ,R_FR ,R_NO ,R_AL, R_NO, R_NO },
|
||||
/*HUMANMILITAR*/{ R_NO ,R_NO ,R_HT ,R_DL ,R_NO ,R_HT ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_HT, R_NO, R_NO },
|
||||
/*ALIENMILITAR*/{ R_NO ,R_DL ,R_HT ,R_DL ,R_HT ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_DL, R_NO, R_NO },
|
||||
/*ALIENPASSIVE*/{ R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO, R_NO, R_NO },
|
||||
/*ALIENMONSTER*/{ R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_DL, R_NO, R_NO },
|
||||
/*ALIENPREY */{ R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_NO ,R_FR ,R_NO ,R_DL, R_NO, R_NO },
|
||||
/*ALIENPREDATO*/{ R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_HT ,R_DL ,R_NO ,R_DL, R_NO, R_NO },
|
||||
/*INSECT*/ { R_FR ,R_FR ,R_FR ,R_FR ,R_FR ,R_NO ,R_FR ,R_FR ,R_FR ,R_FR ,R_NO ,R_FR, R_NO, R_NO },
|
||||
/*PLAYERALLY*/ { R_NO ,R_DL ,R_AL ,R_AL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO, R_NO, R_NO },
|
||||
/*PBIOWEAPON*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_DL, R_NO, R_DL },
|
||||
/*ABIOWEAPON*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_AL ,R_NO ,R_DL ,R_DL ,R_NO ,R_NO ,R_DL, R_DL, R_NO }
|
||||
static int iEnemy[15][15] =
|
||||
{ // NONE MACH PLYR HPASS HMIL AMIL APASS AMONST APREY APRED INSECT PLRALY PBWPN ABWPN SKELETON
|
||||
/*NONE*/ { R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO, R_NO, R_NO, R_NO },
|
||||
/*MACHINE*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_DL, R_DL, R_DL, R_DL },
|
||||
/*PLAYER*/ { R_NO ,R_DL ,R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO, R_DL, R_DL, R_DL },
|
||||
/*HUMANPASSIVE*/{ R_NO ,R_NO ,R_AL ,R_AL ,R_HT ,R_FR ,R_NO ,R_HT ,R_DL ,R_FR ,R_NO ,R_AL, R_NO, R_NO, R_HT },
|
||||
/*HUMANMILITAR*/{ R_NO ,R_NO ,R_HT ,R_DL ,R_NO ,R_HT ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_HT, R_NO, R_NO, R_DL },
|
||||
/*ALIENMILITAR*/{ R_NO ,R_DL ,R_HT ,R_DL ,R_HT ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_DL, R_NO, R_NO, R_NO },
|
||||
/*ALIENPASSIVE*/{ R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO, R_NO, R_NO, R_NO },
|
||||
/*ALIENMONSTER*/{ R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_DL, R_NO, R_NO, R_NO },
|
||||
/*ALIENPREY */{ R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_NO ,R_FR ,R_NO ,R_DL, R_NO, R_NO, R_NO },
|
||||
/*ALIENPREDATO*/{ R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_HT ,R_DL ,R_NO ,R_DL, R_NO, R_NO, R_NO },
|
||||
/*INSECT*/ { R_FR ,R_FR ,R_FR ,R_FR ,R_FR ,R_NO ,R_FR ,R_FR ,R_FR ,R_FR ,R_NO ,R_FR, R_NO, R_NO, R_FR },
|
||||
/*PLAYERALLY*/ { R_NO ,R_DL ,R_AL ,R_AL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO, R_NO, R_NO, R_DL },
|
||||
/*PBIOWEAPON*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_DL, R_NO, R_DL, R_DL },
|
||||
/*ABIOWEAPON*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_AL ,R_NO ,R_DL ,R_DL ,R_NO ,R_NO ,R_DL, R_DL, R_NO, R_DL },
|
||||
/*SKELETON*/ { R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_DL, R_NO, R_NO, R_NO }
|
||||
};
|
||||
|
||||
return iEnemy[Classify()][pTarget->Classify()];
|
||||
|
|
|
@ -45,11 +45,12 @@
|
|||
#define SF_MONSTER_HITMONSTERCLIP 4
|
||||
// 8
|
||||
#define SF_MONSTER_PRISONER 16 // monster won't attack anyone, no one will attacke him.
|
||||
// 32
|
||||
// 64
|
||||
#define SF_MONSTER_REDBLOOD 32
|
||||
#define SF_MONSTER_ZOMBIECOP 64
|
||||
#define SF_MONSTER_WAIT_FOR_SCRIPT 128 //spawnflag that makes monsters wait to check for attacking until the script is done or they've been attacked
|
||||
#define SF_MONSTER_PREDISASTER 256 //this is a predisaster scientist or barney. Influences how they speak.
|
||||
#define SF_MONSTER_FADECORPSE 512 // Fade out corpse after death
|
||||
#define SF_MONSTER_FASTZOMBIEMODE 1024
|
||||
#define SF_MONSTER_FALL_TO_GROUND 0x80000000
|
||||
|
||||
// specialty spawnflags
|
||||
|
|
|
@ -1063,7 +1063,17 @@ void CFuncTrackTrain::StopSound( void )
|
|||
/*
|
||||
STOP_SOUND( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noise ) );
|
||||
*/
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_ITEM, "plats/ttrain_brake1.wav", m_flVolume, ATTN_NORM, 0, 100 );
|
||||
char *brake = "plats/ttrain_brake1.wav";
|
||||
|
||||
if( UseCustomSounds() )
|
||||
{
|
||||
if( IsCar() )
|
||||
brake = "plats/ttrain_brake2.wav";
|
||||
else if( IsTrain() )
|
||||
brake = "plats/ttrain_brake6.wav";
|
||||
}
|
||||
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_ITEM, brake, m_flVolume, ATTN_NORM, 0, 100 );
|
||||
}
|
||||
|
||||
m_soundPlaying = 0;
|
||||
|
@ -1084,7 +1094,17 @@ void CFuncTrackTrain::UpdateSound( void )
|
|||
if( !m_soundPlaying )
|
||||
{
|
||||
// play startup sound for train
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_ITEM, "plats/ttrain_start1.wav", m_flVolume, ATTN_NORM, 0, 100 );
|
||||
char *start = "plats/ttrain_start1.wav";
|
||||
|
||||
if( UseCustomSounds() )
|
||||
{
|
||||
if( IsCar() )
|
||||
start = "plats/ttrain_start2.wav";
|
||||
else if( IsTrain() )
|
||||
start = "plats/ttrain_start6.wav";
|
||||
}
|
||||
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_ITEM, start, m_flVolume, ATTN_NORM, 0, 100 );
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_STATIC, (char*)STRING( pev->noise ), m_flVolume, ATTN_NORM, 0, (int)flpitch );
|
||||
m_soundPlaying = 1;
|
||||
}
|
||||
|
@ -1509,9 +1529,30 @@ void CFuncTrackTrain::Precache( void )
|
|||
PRECACHE_SOUND( "plats/ttrain_brake1.wav" );
|
||||
PRECACHE_SOUND( "plats/ttrain_start1.wav" );
|
||||
|
||||
PRECACHE_SOUND( "plats/ttrain_brake2.wav" );
|
||||
PRECACHE_SOUND( "plats/ttrain_start2.wav" );
|
||||
|
||||
PRECACHE_SOUND( "plats/ttrain_brake6.wav" );
|
||||
PRECACHE_SOUND( "plats/ttrain_start6.wav" );
|
||||
|
||||
m_usAdjustPitch = PRECACHE_EVENT( 1, "events/train.sc" );
|
||||
}
|
||||
|
||||
BOOL CFuncTrackTrain::UseCustomSounds( void ) const
|
||||
{
|
||||
return ( pev->spawnflags & SF_TRACKTRAIN_TH_SOUNDS );
|
||||
}
|
||||
|
||||
BOOL CFuncTrackTrain::IsCar( void ) const
|
||||
{
|
||||
return FStrEq( STRING( pev->noise ), "plats/ttrain2.wav" );
|
||||
}
|
||||
|
||||
BOOL CFuncTrackTrain::IsTrain(void) const
|
||||
{
|
||||
return FStrEq( STRING( pev->noise ), "plats/ttrain6.wav" );
|
||||
}
|
||||
|
||||
// This class defines the volume of space that the player must stand in to control the train
|
||||
class CFuncTrainControls : public CBaseEntity
|
||||
{
|
||||
|
|
118
dlls/player.cpp
118
dlls/player.cpp
|
@ -184,6 +184,8 @@ int gmsgTeamNames = 0;
|
|||
int gmsgStatusText = 0;
|
||||
int gmsgStatusValue = 0;
|
||||
|
||||
int gmsgZoom = 0;
|
||||
|
||||
void LinkUserMessages( void )
|
||||
{
|
||||
// Already taken care of?
|
||||
|
@ -228,6 +230,8 @@ void LinkUserMessages( void )
|
|||
|
||||
gmsgStatusText = REG_USER_MSG( "StatusText", -1 );
|
||||
gmsgStatusValue = REG_USER_MSG( "StatusValue", 3 );
|
||||
|
||||
gmsgZoom = REG_USER_MSG( "Zoom", 2 );
|
||||
}
|
||||
|
||||
LINK_ENTITY_TO_CLASS( player, CBasePlayer )
|
||||
|
@ -1092,6 +1096,9 @@ void CBasePlayer::TabulateAmmo()
|
|||
ammo_rockets = AmmoInventory( GetAmmoIndex( "rockets" ) );
|
||||
ammo_uranium = AmmoInventory( GetAmmoIndex( "uranium" ) );
|
||||
ammo_hornets = AmmoInventory( GetAmmoIndex( "Hornets" ) );
|
||||
ammo_ap9 = AmmoInventory( GetAmmoIndex( "ap9" ) );
|
||||
ammo_taurus = AmmoInventory( GetAmmoIndex( "taurus" ) );
|
||||
ammo_sniper = AmmoInventory( GetAmmoIndex( "sniper" ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1411,7 +1418,19 @@ void CBasePlayer::PlayerUse( void )
|
|||
m_afPhysicsFlags |= PFLAG_ONTRAIN;
|
||||
m_iTrain = TrainSpeed( pTrain->pev->speed, pTrain->pev->impulse );
|
||||
m_iTrain |= TRAIN_NEW;
|
||||
EMIT_SOUND( ENT( pev ), CHAN_ITEM, "plats/train_use1.wav", 0.8, ATTN_NORM );
|
||||
char* usesound = "plats/train_use1.wav";
|
||||
|
||||
CFuncTrackTrain* pTrackTrain = (CFuncTrackTrain*)pTrain;
|
||||
|
||||
if pTrackTrain && pTrackTrain->UseCustomSounds() )
|
||||
{
|
||||
if( pTrackTrain->IsCar() )
|
||||
usesound = "plats/train_use2.wav";
|
||||
else if( pTrackTrain->IsTrain() )
|
||||
usesound = "plats/train_use6.wav";
|
||||
}
|
||||
|
||||
EMIT_SOUND( ENT( pev ), CHAN_ITEM, usesound, 0.8, ATTN_NORM );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2181,89 +2200,6 @@ void CBasePlayer::CheckSuitUpdate()
|
|||
|
||||
void CBasePlayer::SetSuitUpdate( char *name, int fgroup, int iNoRepeatTime )
|
||||
{
|
||||
int i;
|
||||
int isentence;
|
||||
int iempty = -1;
|
||||
|
||||
// Ignore suit updates if no suit
|
||||
if( !( pev->weapons & ( 1 << WEAPON_SUIT ) ) )
|
||||
return;
|
||||
|
||||
if( g_pGameRules->IsMultiplayer() )
|
||||
{
|
||||
// due to static channel design, etc. We don't play HEV sounds in multiplayer right now.
|
||||
return;
|
||||
}
|
||||
|
||||
// if name == NULL, then clear out the queue
|
||||
if( !name )
|
||||
{
|
||||
for( i = 0; i < CSUITPLAYLIST; i++ )
|
||||
m_rgSuitPlayList[i] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// get sentence or group number
|
||||
if( !fgroup )
|
||||
{
|
||||
isentence = SENTENCEG_Lookup( name, NULL );
|
||||
if( isentence < 0 )
|
||||
return;
|
||||
}
|
||||
else
|
||||
// mark group number as negative
|
||||
isentence = -SENTENCEG_GetIndex( name );
|
||||
|
||||
// check norepeat list - this list lets us cancel
|
||||
// the playback of words or sentences that have already
|
||||
// been played within a certain time.
|
||||
for( i = 0; i < CSUITNOREPEAT; i++ )
|
||||
{
|
||||
if( isentence == m_rgiSuitNoRepeat[i] )
|
||||
{
|
||||
// this sentence or group is already in
|
||||
// the norepeat list
|
||||
if( m_rgflSuitNoRepeatTime[i] < gpGlobals->time )
|
||||
{
|
||||
// norepeat time has expired, clear it out
|
||||
m_rgiSuitNoRepeat[i] = 0;
|
||||
m_rgflSuitNoRepeatTime[i] = 0.0;
|
||||
iempty = i;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't play, still marked as norepeat
|
||||
return;
|
||||
}
|
||||
}
|
||||
// keep track of empty slot
|
||||
if( !m_rgiSuitNoRepeat[i] )
|
||||
iempty = i;
|
||||
}
|
||||
|
||||
// sentence is not in norepeat list, save if norepeat time was given
|
||||
if( iNoRepeatTime )
|
||||
{
|
||||
if( iempty < 0 )
|
||||
iempty = RANDOM_LONG( 0, CSUITNOREPEAT - 1 ); // pick random slot to take over
|
||||
m_rgiSuitNoRepeat[iempty] = isentence;
|
||||
m_rgflSuitNoRepeatTime[iempty] = iNoRepeatTime + gpGlobals->time;
|
||||
}
|
||||
|
||||
// find empty spot in queue, or overwrite last spot
|
||||
m_rgSuitPlayList[m_iSuitPlayNext++] = isentence;
|
||||
if( m_iSuitPlayNext == CSUITPLAYLIST )
|
||||
m_iSuitPlayNext = 0;
|
||||
|
||||
if( m_flSuitUpdate <= gpGlobals->time )
|
||||
{
|
||||
if( m_flSuitUpdate == 0 )
|
||||
// play queue is empty, don't delay too long before playback
|
||||
m_flSuitUpdate = gpGlobals->time + SUITFIRSTUPDATETIME;
|
||||
else
|
||||
m_flSuitUpdate = gpGlobals->time + SUITUPDATETIME;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3347,7 +3283,6 @@ void CBasePlayer::CheatImpulseCommands( int iImpulse )
|
|||
case 101:
|
||||
gEvilImpulse101 = TRUE;
|
||||
GiveNamedItem( "item_suit" );
|
||||
GiveNamedItem( "item_battery" );
|
||||
GiveNamedItem( "weapon_crowbar" );
|
||||
GiveNamedItem( "weapon_9mmhandgun" );
|
||||
GiveNamedItem( "ammo_9mmclip" );
|
||||
|
@ -3370,8 +3305,19 @@ void CBasePlayer::CheatImpulseCommands( int iImpulse )
|
|||
GiveNamedItem( "ammo_rpgclip" );
|
||||
GiveNamedItem( "weapon_satchel" );
|
||||
GiveNamedItem( "weapon_snark" );
|
||||
GiveNamedItem( "weapon_hornetgun" );
|
||||
#endif
|
||||
GiveNamedItem( "weapon_th_ap9" );
|
||||
GiveNamedItem( "ammo_th_ap9" );
|
||||
GiveNamedItem( "weapon_th_chaingun" );
|
||||
GiveNamedItem( "weapon_th_medkit" );
|
||||
GiveNamedItem( "weapon_th_shovel" );
|
||||
GiveNamedItem( "weapon_einar1" );
|
||||
GiveNamedItem( "weapon_th_sniper" );
|
||||
GiveNamedItem( "ammo_th_sniper" );
|
||||
GiveNamedItem( "weapon_th_spanner" );
|
||||
GiveNamedItem( "weapon_th_taurus" );
|
||||
GiveNamedItem( "ammo_th_taurus" );
|
||||
|
||||
gEvilImpulse101 = FALSE;
|
||||
break;
|
||||
case 102:
|
||||
|
|
|
@ -75,6 +75,8 @@ void CPython::Spawn()
|
|||
|
||||
m_iDefaultAmmo = PYTHON_DEFAULT_GIVE;
|
||||
|
||||
m_flSoundDelay = 0;
|
||||
|
||||
FallInit();// get ready to fall down.
|
||||
}
|
||||
|
||||
|
@ -227,9 +229,11 @@ 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 +244,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;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "scripted.h"
|
||||
#include "animation.h"
|
||||
#include "soundent.h"
|
||||
#include "scientist.h"
|
||||
|
||||
#define NUM_SCIENTIST_HEADS 4 // four heads available for scientist model
|
||||
|
||||
|
@ -37,6 +38,16 @@ enum
|
|||
HEAD_SLICK = 3
|
||||
};
|
||||
|
||||
#define NUM_SCIENTIST_SKINS 4
|
||||
|
||||
enum
|
||||
{
|
||||
SKIN_GLASSES = 0,
|
||||
SKIN_DOCTOR = 1,
|
||||
SKIN_PREIST = 2,
|
||||
SKIN_PATIENT = 3
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SCHED_HIDE = LAST_TALKMONSTER_SCHEDULE + 1,
|
||||
|
@ -68,56 +79,6 @@ enum
|
|||
//=======================================================
|
||||
// Scientist
|
||||
//=======================================================
|
||||
class CScientist : public CTalkMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
|
||||
void SetYawSpeed( void );
|
||||
int Classify( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
void RunTask( Task_t *pTask );
|
||||
void StartTask( Task_t *pTask );
|
||||
int ObjectCaps( void ) { return CTalkMonster::ObjectCaps() | FCAP_IMPULSE_USE; }
|
||||
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
|
||||
virtual int FriendNumber( int arrayNumber );
|
||||
void SetActivity( Activity newActivity );
|
||||
Activity GetStoppedActivity( void );
|
||||
int ISoundMask( void );
|
||||
void DeclineFollowing( void );
|
||||
|
||||
float CoverRadius( void ) { return 1200; } // Need more room for cover because scientists want to get far away!
|
||||
BOOL DisregardEnemy( CBaseEntity *pEnemy ) { return !pEnemy->IsAlive() || ( gpGlobals->time - m_fearTime ) > 15; }
|
||||
|
||||
BOOL CanHeal( void );
|
||||
void Heal( void );
|
||||
void Scream( void );
|
||||
|
||||
// Override these to set behavior
|
||||
Schedule_t *GetScheduleOfType( int Type );
|
||||
Schedule_t *GetSchedule( void );
|
||||
MONSTERSTATE GetIdealState( void );
|
||||
|
||||
void DeathSound( void );
|
||||
void PainSound( void );
|
||||
|
||||
void TalkInit( void );
|
||||
|
||||
void Killed( entvars_t *pevAttacker, int iGib );
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
CUSTOM_SCHEDULES
|
||||
|
||||
private:
|
||||
float m_painTime;
|
||||
float m_healTime;
|
||||
float m_fearTime;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_scientist, CScientist )
|
||||
|
||||
TYPEDESCRIPTION CScientist::m_SaveData[] =
|
||||
|
@ -651,19 +612,12 @@ void CScientist::Spawn( void )
|
|||
|
||||
m_afCapability = bits_CAP_HEAR | bits_CAP_TURN_HEAD | bits_CAP_OPEN_DOORS | bits_CAP_AUTO_DOORS | bits_CAP_USE;
|
||||
|
||||
// White hands
|
||||
pev->skin = 0;
|
||||
|
||||
if( pev->body == -1 )
|
||||
{
|
||||
// -1 chooses a random head
|
||||
pev->body = RANDOM_LONG( 0, NUM_SCIENTIST_HEADS - 1 );// pick a head, any head
|
||||
}
|
||||
|
||||
// Luther is black, make his hands black
|
||||
if( pev->body == HEAD_LUTHER )
|
||||
pev->skin = 1;
|
||||
|
||||
MonsterInit();
|
||||
SetUse( &CTalkMonster::FollowerUse );
|
||||
}
|
||||
|
@ -1050,10 +1004,7 @@ MONSTERSTATE CScientist::GetIdealState( void )
|
|||
|
||||
BOOL CScientist::CanHeal( void )
|
||||
{
|
||||
if( ( m_healTime > gpGlobals->time ) || ( m_hTargetEnt == NULL ) || ( m_hTargetEnt->pev->health > ( m_hTargetEnt->pev->max_health * 0.5 ) ) )
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CScientist::Heal( void )
|
||||
|
@ -1082,20 +1033,6 @@ int CScientist::FriendNumber( int arrayNumber )
|
|||
//=========================================================
|
||||
// Dead Scientist PROP
|
||||
//=========================================================
|
||||
class CDeadScientist : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
int Classify( void )
|
||||
{
|
||||
return CLASS_HUMAN_PASSIVE;
|
||||
}
|
||||
|
||||
void KeyValue( KeyValueData *pkvd );
|
||||
int m_iPose;// which sequence to display
|
||||
static char *m_szPoses[7];
|
||||
};
|
||||
|
||||
char *CDeadScientist::m_szPoses[] =
|
||||
{
|
||||
"lying_on_back",
|
||||
|
@ -1141,12 +1078,6 @@ void CDeadScientist::Spawn()
|
|||
pev->body = RANDOM_LONG( 0, NUM_SCIENTIST_HEADS - 1 );// pick a head, any head
|
||||
}
|
||||
|
||||
// Luther is black, make his hands black
|
||||
if( pev->body == HEAD_LUTHER )
|
||||
pev->skin = 1;
|
||||
else
|
||||
pev->skin = 0;
|
||||
|
||||
pev->sequence = LookupSequence( m_szPoses[m_iPose] );
|
||||
if( pev->sequence == -1 )
|
||||
{
|
||||
|
@ -1160,27 +1091,6 @@ void CDeadScientist::Spawn()
|
|||
//=========================================================
|
||||
// Sitting Scientist PROP
|
||||
//=========================================================
|
||||
class CSittingScientist : public CScientist // kdb: changed from public CBaseMonster so he can speak
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
|
||||
void EXPORT SittingThink( void );
|
||||
int Classify( void );
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
virtual void SetAnswerQuestion( CTalkMonster *pSpeaker );
|
||||
int FriendNumber( int arrayNumber );
|
||||
|
||||
int FIdleSpeak( void );
|
||||
int m_baseSequence;
|
||||
int m_headTurn;
|
||||
float m_flResponseDelay;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_sitting_scientist, CSittingScientist )
|
||||
|
||||
TYPEDESCRIPTION CSittingScientist::m_SaveData[] =
|
||||
|
@ -1232,10 +1142,6 @@ void CSittingScientist::Spawn()
|
|||
pev->body = RANDOM_LONG( 0, NUM_SCIENTIST_HEADS - 1 );// pick a head, any head
|
||||
}
|
||||
|
||||
// Luther is black, make his hands black
|
||||
if( pev->body == HEAD_LUTHER )
|
||||
pev->skin = 1;
|
||||
|
||||
m_baseSequence = LookupSequence( "sitlookleft" );
|
||||
pev->sequence = m_baseSequence + RANDOM_LONG( 0, 4 );
|
||||
ResetSequenceInfo();
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/***
|
||||
*
|
||||
* 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 SCIENTIST_H
|
||||
#define SCIENTIST_H
|
||||
|
||||
//=======================================================
|
||||
// Scientist
|
||||
//=======================================================
|
||||
class CScientist : public CTalkMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
|
||||
void SetYawSpeed( void );
|
||||
int Classify ( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
void RunTask( Task_t *pTask );
|
||||
void StartTask( Task_t *pTask );
|
||||
int ObjectCaps( void ) { return CTalkMonster :: ObjectCaps() | FCAP_IMPULSE_USE; }
|
||||
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType);
|
||||
virtual int FriendNumber( int arrayNumber );
|
||||
void SetActivity ( Activity newActivity );
|
||||
Activity GetStoppedActivity( void );
|
||||
int ISoundMask( void );
|
||||
void DeclineFollowing( void );
|
||||
|
||||
float CoverRadius( void ) { return 1200; } // Need more room for cover because scientists want to get far away!
|
||||
BOOL DisregardEnemy( CBaseEntity *pEnemy ) { return !pEnemy->IsAlive() || (gpGlobals->time - m_fearTime) > 15; }
|
||||
|
||||
BOOL CanHeal( void );
|
||||
void Heal( void );
|
||||
void Scream( void );
|
||||
|
||||
// Override these to set behavior
|
||||
Schedule_t *GetScheduleOfType ( int Type );
|
||||
Schedule_t *GetSchedule ( void );
|
||||
MONSTERSTATE GetIdealState ( void );
|
||||
|
||||
void DeathSound( void );
|
||||
void PainSound( void );
|
||||
|
||||
void TalkInit( void );
|
||||
|
||||
void Killed( entvars_t *pevAttacker, int iGib );
|
||||
|
||||
virtual int Save( CSave &save );
|
||||
virtual int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
CUSTOM_SCHEDULES;
|
||||
|
||||
private:
|
||||
float m_painTime;
|
||||
float m_healTime;
|
||||
float m_fearTime;
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Dead Scientist PROP
|
||||
//=========================================================
|
||||
class CDeadScientist : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
int Classify(void) { return CLASS_HUMAN_PASSIVE; }
|
||||
|
||||
void KeyValue(KeyValueData *pkvd);
|
||||
int m_iPose;// which sequence to display
|
||||
static char *m_szPoses[7];
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Sitting Scientist PROP
|
||||
//=========================================================
|
||||
class CSittingScientist : public CScientist // kdb: changed from public CBaseMonster so he can speak
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
|
||||
void EXPORT SittingThink(void);
|
||||
int Classify(void);
|
||||
virtual int Save(CSave &save);
|
||||
virtual int Restore(CRestore &restore);
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
virtual void SetAnswerQuestion(CTalkMonster *pSpeaker);
|
||||
int FriendNumber(int arrayNumber);
|
||||
|
||||
int FIdleSpeak(void);
|
||||
int m_baseSequence;
|
||||
int m_headTurn;
|
||||
float m_flResponseDelay;
|
||||
};
|
||||
|
||||
#endif // SCIENTIST_H
|
26
dlls/skill.h
26
dlls/skill.h
|
@ -133,6 +133,32 @@ struct skilldata_t
|
|||
float plrStomach;
|
||||
float plrLeg;
|
||||
float plrArm;
|
||||
|
||||
// Monster Health & Damage
|
||||
float babykellyhealth;
|
||||
|
||||
float bossHealth;
|
||||
|
||||
float cyberfranklinHealth;
|
||||
|
||||
float houndeyeDmgBite;
|
||||
|
||||
float megasquidHealth;
|
||||
|
||||
float zombiebullHealth;
|
||||
float zombiebullDmgBite;
|
||||
float zombiebullDmgWhip;
|
||||
|
||||
// health/suit charge
|
||||
float medkitHeal;
|
||||
|
||||
// Player Weapons
|
||||
float plrDmgShovel;
|
||||
float plrDmgSpanner;
|
||||
float plrDmgAP9;
|
||||
float plrDmgTaurus;
|
||||
float plrDmgSniper;
|
||||
float plrDmgFlame;
|
||||
};
|
||||
|
||||
extern DLL_GLOBAL skilldata_t gSkillData;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#define SF_SQUADMONSTER_LEADER 32
|
||||
|
||||
#define SF_SQUADMONSTER_NOZAP 256
|
||||
|
||||
#define bits_NO_SLOT 0
|
||||
|
||||
// HUMAN GRUNT SLOTS
|
||||
|
|
|
@ -50,7 +50,7 @@ class CSqueakGrenade : public CGrenade
|
|||
int Classify( void );
|
||||
void EXPORT SuperBounceTouch( CBaseEntity *pOther );
|
||||
void EXPORT HuntThink( void );
|
||||
int BloodColor( void ) { return BLOOD_COLOR_YELLOW; }
|
||||
int BloodColor( void ) { return BLOOD_COLOR_RED; }
|
||||
void Killed( entvars_t *pevAttacker, int iGib );
|
||||
void GibMonster( void );
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "scripted.h"
|
||||
#include "soundent.h"
|
||||
#include "animation.h"
|
||||
#include "barney.h"
|
||||
|
||||
//=========================================================
|
||||
// Talking monster base class
|
||||
|
@ -644,6 +645,10 @@ CBaseEntity *CTalkMonster::EnumFriends( CBaseEntity *pPrevious, int listNumber,
|
|||
|
||||
void CTalkMonster::AlertFriends( void )
|
||||
{
|
||||
// Do not alert friends if this is a zombie cop.
|
||||
if( FClassnameIs( pev, "monster_barney" ) && ( (CBarney*)this )->IsZombieCop() )
|
||||
return;
|
||||
|
||||
CBaseEntity *pFriend = NULL;
|
||||
int i;
|
||||
|
||||
|
@ -653,7 +658,7 @@ void CTalkMonster::AlertFriends( void )
|
|||
while( ( pFriend = EnumFriends( pFriend, i, TRUE ) ) )
|
||||
{
|
||||
CBaseMonster *pMonster = pFriend->MyMonsterPointer();
|
||||
if( pMonster->IsAlive() )
|
||||
if( pMonster->IsAlive() && pMonster->Classify() == Classify() )
|
||||
{
|
||||
// don't provoke a friend that's playing a death animation. They're a goner
|
||||
pMonster->m_afMemory |= bits_MEMORY_PROVOKED;
|
||||
|
@ -1147,9 +1152,13 @@ int CTalkMonster::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, f
|
|||
// if player damaged this entity, have other friends talk about it
|
||||
if( pevAttacker && m_MonsterState != MONSTERSTATE_PRONE && FBitSet( pevAttacker->flags, FL_CLIENT ) )
|
||||
{
|
||||
// Do not tell friends to stop shooting if this is a zombie cop.
|
||||
if( FClassnameIs( pev, "monster_barney" ) && ( (CBarney*)this )->IsZombieCop() )
|
||||
return CBaseMonster::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType );
|
||||
|
||||
CBaseEntity *pFriend = FindNearestFriend( FALSE );
|
||||
|
||||
if( pFriend && pFriend->IsAlive() )
|
||||
if( pFriend && pFriend->IsAlive() && pFriend->Classify() == Classify() )
|
||||
{
|
||||
// only if not dead or dying!
|
||||
CTalkMonster *pTalkMonster = (CTalkMonster *)pFriend;
|
||||
|
@ -1190,8 +1199,12 @@ Schedule_t *CTalkMonster::GetScheduleOfType( int Type )
|
|||
{
|
||||
//SENTENCEG_PlayRndSz( ENT( pev ), m_szGrp[TLK_WOUND], 1.0, ATTN_IDLE, 0, GetVoicePitch() );
|
||||
//CTalkMonster::g_talkWaitTime = gpGlobals->time + RANDOM_FLOAT( 2.8, 3.2 );
|
||||
PlaySentence( m_szGrp[TLK_WOUND], RANDOM_FLOAT( 2.8, 3.2 ), VOL_NORM, ATTN_IDLE );
|
||||
SetBits( m_bitsSaid, bit_saidWoundLight );
|
||||
|
||||
if( FWoundSpeak() )
|
||||
{
|
||||
SetBits( m_bitsSaid, bit_saidWoundLight );
|
||||
}
|
||||
|
||||
return slIdleStand;
|
||||
}
|
||||
// sustained heavy wounds?
|
||||
|
@ -1199,8 +1212,12 @@ Schedule_t *CTalkMonster::GetScheduleOfType( int Type )
|
|||
{
|
||||
//SENTENCEG_PlayRndSz( ENT( pev ), m_szGrp[TLK_MORTAL], 1.0, ATTN_IDLE, 0, GetVoicePitch() );
|
||||
//CTalkMonster::g_talkWaitTime = gpGlobals->time + RANDOM_FLOAT( 2.8, 3.2 );
|
||||
PlaySentence( m_szGrp[TLK_MORTAL], RANDOM_FLOAT( 2.8, 3.2 ), VOL_NORM, ATTN_IDLE );
|
||||
SetBits( m_bitsSaid, bit_saidWoundHeavy );
|
||||
|
||||
if( FMortalSpeak() )
|
||||
{
|
||||
SetBits( m_bitsSaid, bit_saidWoundHeavy );
|
||||
}
|
||||
|
||||
return slIdleStand;
|
||||
}
|
||||
|
||||
|
@ -1407,3 +1424,24 @@ void CTalkMonster::Precache( void )
|
|||
if( m_iszUnUse )
|
||||
m_szGrp[TLK_UNUSE] = STRING( m_iszUnUse );
|
||||
}
|
||||
|
||||
int CTalkMonster::FWoundSpeak( void )
|
||||
{
|
||||
if( !FOkToSpeak() )
|
||||
return FALSE;
|
||||
|
||||
PlaySentence( m_szGrp[TLK_WOUND], RANDOM_FLOAT( 2.8, 3.2 ), VOL_NORM, ATTN_IDLE );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int CTalkMonster::FMortalSpeak( void )
|
||||
{
|
||||
if( !FOkToSpeak() )
|
||||
return FALSE;
|
||||
|
||||
PlaySentence( m_szGrp[TLK_MORTAL], RANDOM_FLOAT( 2.8, 3.2 ), VOL_NORM, ATTN_IDLE );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,12 +123,14 @@ public:
|
|||
|
||||
// Conversations / communication
|
||||
int GetVoicePitch( void );
|
||||
void IdleRespond( void );
|
||||
virtual void IdleRespond( void );
|
||||
int FIdleSpeak( void );
|
||||
int FIdleStare( void );
|
||||
int FIdleHello( void );
|
||||
void IdleHeadTurn( Vector &vecFriend );
|
||||
int FOkToSpeak( void );
|
||||
virtual int FOkToSpeak( void );
|
||||
int FWoundSpeak( void );
|
||||
int FMortalSpeak( void );
|
||||
void TrySmellTalk( void );
|
||||
CBaseEntity *EnumFriends( CBaseEntity *pentPrevious, int listNumber, BOOL bTrace );
|
||||
void AlertFriends( void );
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define SF_TRACKTRAIN_NOCONTROL 0x0002
|
||||
#define SF_TRACKTRAIN_FORWARDONLY 0x0004
|
||||
#define SF_TRACKTRAIN_PASSABLE 0x0008
|
||||
#define SF_TRACKTRAIN_TH_SOUNDS 0x0020
|
||||
|
||||
// Spawnflag for CPathTrack
|
||||
#define SF_PATH_DISABLED 0x00000001
|
||||
|
@ -118,6 +119,10 @@ public:
|
|||
float m_flBank;
|
||||
float m_oldSpeed;
|
||||
|
||||
BOOL UseCustomSounds( void ) const;
|
||||
BOOL IsCar( void ) const;
|
||||
BOOL IsTrain( void ) const;
|
||||
|
||||
private:
|
||||
unsigned short m_usAdjustPitch;
|
||||
};
|
||||
|
|
112
dlls/weapons.cpp
112
dlls/weapons.cpp
|
@ -46,6 +46,8 @@ DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model
|
|||
DLL_GLOBAL short g_sModelIndexBloodDrop;// holds the sprite index for the initial blood
|
||||
DLL_GLOBAL short g_sModelIndexBloodSpray;// holds the sprite index for splattered blood
|
||||
|
||||
DLL_GLOBAL short g_sModelIndexFThrow; // holds the index for the flamethrower
|
||||
|
||||
ItemInfo CBasePlayerItem::ItemInfoArray[MAX_WEAPONS];
|
||||
AmmoInfo CBasePlayerItem::AmmoInfoArray[MAX_AMMO_SLOTS];
|
||||
|
||||
|
@ -169,6 +171,10 @@ void DecalGunshot( TraceResult *pTrace, int iBulletType )
|
|||
case BULLET_MONSTER_MP5:
|
||||
case BULLET_PLAYER_BUCKSHOT:
|
||||
case BULLET_PLAYER_357:
|
||||
case BULLET_PLAYER_AP9:
|
||||
case BULLET_PLAYER_CHAINGUN:
|
||||
case BULLET_PLAYER_SNIPER:
|
||||
case BULLET_PLAYER_TAURUS:
|
||||
default:
|
||||
// smoke and decal
|
||||
UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) );
|
||||
|
@ -347,10 +353,33 @@ void W_Precache( void )
|
|||
#if !defined( OEM_BUILD ) && !defined( HLDEMO_BUILD )
|
||||
// squeak grenade
|
||||
UTIL_PrecacheOtherWeapon( "weapon_snark" );
|
||||
#endif
|
||||
// ap9
|
||||
UTIL_PrecacheOtherWeapon( "weapon_th_ap9" );
|
||||
UTIL_PrecacheOther( "ammo_th_ap9" );
|
||||
|
||||
// hornetgun
|
||||
UTIL_PrecacheOtherWeapon( "weapon_hornetgun" );
|
||||
// chaingun
|
||||
UTIL_PrecacheOtherWeapon( "weapon_th_chaingun" );
|
||||
|
||||
// medkit
|
||||
UTIL_PrecacheOtherWeapon( "weapon_th_medkit" );
|
||||
|
||||
// shovel
|
||||
UTIL_PrecacheOtherWeapon( "weapon_th_shovel" );
|
||||
|
||||
// sniper
|
||||
UTIL_PrecacheOtherWeapon( "weapon_einar1" );
|
||||
UTIL_PrecacheOtherWeapon( "weapon_th_sniper" );
|
||||
UTIL_PrecacheOther( "ammo_th_sniper" );
|
||||
|
||||
// spanner
|
||||
UTIL_PrecacheOtherWeapon( "weapon_th_spanner" );
|
||||
|
||||
// taurus
|
||||
UTIL_PrecacheOtherWeapon( "weapon_th_taurus" );
|
||||
UTIL_PrecacheOther( "ammo_th_taurus" );
|
||||
|
||||
#if !defined( OEM_BUILD ) && !defined( HLDEMO_BUILD )
|
||||
if( g_pGameRules->IsDeathmatch() )
|
||||
{
|
||||
UTIL_PrecacheOther( "weaponbox" );// container for dropped deathmatch weapons
|
||||
|
@ -366,6 +395,8 @@ void W_Precache( void )
|
|||
g_sModelIndexLaser = PRECACHE_MODEL( (char *)g_pModelNameLaser );
|
||||
g_sModelIndexLaserDot = PRECACHE_MODEL( "sprites/laserdot.spr" );
|
||||
|
||||
g_sModelIndexFThrow = PRECACHE_MODEL( "sprites/fthrow.spr" );
|
||||
|
||||
// used by explosions
|
||||
PRECACHE_MODEL( "models/grenade.mdl" );
|
||||
PRECACHE_MODEL( "sprites/explode1.spr" );
|
||||
|
@ -382,6 +413,9 @@ void W_Precache( void )
|
|||
PRECACHE_SOUND( "weapons/bullet_hit2.wav" ); // hit by bullet
|
||||
|
||||
PRECACHE_SOUND( "items/weapondrop1.wav" );// weapon falls to the ground
|
||||
|
||||
// Precached here since hand grenade no longer precaches it.
|
||||
PRECACHE_MODEL( "models/w_grenade.mdl" );
|
||||
}
|
||||
|
||||
TYPEDESCRIPTION CBasePlayerItem::m_SaveData[] =
|
||||
|
@ -612,6 +646,11 @@ void CBasePlayerWeapon::ItemPostFrame( void )
|
|||
m_fInReload = FALSE;
|
||||
}
|
||||
|
||||
if( !( m_pPlayer->pev->button & IN_ATTACK ) )
|
||||
{
|
||||
m_flLastFireTime = 0.0f;
|
||||
}
|
||||
|
||||
if( ( m_pPlayer->pev->button & IN_ATTACK2 ) && CanAttack( m_flNextSecondaryAttack, gpGlobals->time, UseDecrement() ) )
|
||||
{
|
||||
if( pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()] )
|
||||
|
@ -943,6 +982,7 @@ BOOL CBasePlayerWeapon::DefaultDeploy( char *szViewModel, char *szWeaponModel, i
|
|||
|
||||
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0;
|
||||
m_flLastFireTime = 0.0f;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1130,6 +1170,37 @@ void CBasePlayerWeapon::RetireWeapon( void )
|
|||
g_pGameRules->GetNextBestWeapon( m_pPlayer, this );
|
||||
}
|
||||
|
||||
/=========================================================================
|
||||
// GetNextAttackDelay - An accurate way of calcualting the next attack time.
|
||||
//=========================================================================
|
||||
float CBasePlayerWeapon::GetNextAttackDelay( float delay )
|
||||
{
|
||||
if( m_flLastFireTime == 0 || m_flNextPrimaryAttack == -1 )
|
||||
{
|
||||
// At this point, we are assuming that the client has stopped firing
|
||||
// and we are going to reset our book keeping variables.
|
||||
m_flLastFireTime = gpGlobals->time;
|
||||
m_flPrevPrimaryAttack = delay;
|
||||
}
|
||||
|
||||
// calculate the time between this shot and the previous
|
||||
float flTimeBetweenFires = gpGlobals->time - m_flLastFireTime;
|
||||
float flCreep = 0.0f;
|
||||
if( flTimeBetweenFires > 0 )
|
||||
flCreep = flTimeBetweenFires - m_flPrevPrimaryAttack; // postive or negative
|
||||
|
||||
// save the last fire time
|
||||
m_flLastFireTime = gpGlobals->time;
|
||||
|
||||
float flNextAttack = UTIL_WeaponTimeBase() + delay - flCreep;
|
||||
// we need to remember what the m_flNextPrimaryAttack time is set to for each shot,
|
||||
// store it as m_flPrevPrimaryAttack.
|
||||
m_flPrevPrimaryAttack = flNextAttack - UTIL_WeaponTimeBase();
|
||||
//char szMsg[256];
|
||||
//_snprintf( szMsg, sizeof(szMsg), "next attack time: %0.4f\n", gpGlobals->time + flNextAttack );
|
||||
//OutputDebugString( szMsg );
|
||||
return flNextAttack;
|
||||
}
|
||||
//*********************************************************
|
||||
// weaponbox code:
|
||||
//*********************************************************
|
||||
|
@ -1527,3 +1598,40 @@ TYPEDESCRIPTION CSatchel::m_SaveData[] =
|
|||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CSatchel, CBasePlayerWeapon )
|
||||
|
||||
TYPEDESCRIPTION CGlock::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CGlock, m_fSilencerOn, FIELD_BOOLEAN ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CGlock, CBasePlayerWeapon );
|
||||
|
||||
TYPEDESCRIPTION CPython::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CPython, m_flSoundDelay, FIELD_TIME ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CPython, CBasePlayerWeapon );
|
||||
|
||||
TYPEDESCRIPTION CAP9::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CAP9, m_iBurstShots, FIELD_INTEGER ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CAP9, CBasePlayerWeapon );
|
||||
|
||||
TYPEDESCRIPTION CSniper::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CSniper, m_fInZoom, FIELD_BOOLEAN ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CSniper, CBasePlayerWeapon )
|
||||
|
||||
#if 0
|
||||
TYPEDESCRIPTION CEinar1::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( CEinar1, m_fInZoom, FIELD_BOOLEAN ),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( CEinar1, CBasePlayerWeapon )
|
||||
#endif
|
||||
|
|
362
dlls/weapons.h
362
dlls/weapons.h
|
@ -55,6 +55,15 @@ public:
|
|||
BOOL m_fRegisteredSound;// whether or not this grenade has issued its DANGER sound to the world sound list yet.
|
||||
};
|
||||
|
||||
// Timed Tnt
|
||||
class CTnt : public CGrenade
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
|
||||
static CGrenade *ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time );
|
||||
};
|
||||
|
||||
// constant items
|
||||
#define ITEM_HEALTHKIT 1
|
||||
#define ITEM_ANTIDOTE 2
|
||||
|
@ -77,6 +86,13 @@ public:
|
|||
#define WEAPON_TRIPMINE 13
|
||||
#define WEAPON_SATCHEL 14
|
||||
#define WEAPON_SNARK 15
|
||||
#define WEAPON_SHOVEL 16
|
||||
#define WEAPON_SPANNER 17
|
||||
#define WEAPON_AP9 18
|
||||
#define WEAPON_TAURUS 19
|
||||
#define WEAPON_EINAR1 20
|
||||
#define WEAPON_HKG36 21
|
||||
#define WEAPON_MEDKIT 22
|
||||
|
||||
#define WEAPON_ALLWEAPONS (~(1<<WEAPON_SUIT))
|
||||
|
||||
|
@ -101,6 +117,13 @@ public:
|
|||
#define SNARK_WEIGHT 5
|
||||
#define SATCHEL_WEIGHT -10
|
||||
#define TRIPMINE_WEIGHT -10
|
||||
#define SHOVEL_WEIGHT 0
|
||||
#define SPANNER_WEIGHT 0
|
||||
#define AP9_WEIGHT 10
|
||||
#define TAURUS_WEIGHT 10
|
||||
#define SNIPER_WEIGHT 10
|
||||
#define CHAINGUN_WEIGHT 20
|
||||
#define MEDKIT_WEIGHT -1
|
||||
|
||||
// weapon clip/carry ammo capacities
|
||||
#define URANIUM_MAX_CARRY 100
|
||||
|
@ -115,6 +138,11 @@ public:
|
|||
#define SNARK_MAX_CARRY 15
|
||||
#define HORNET_MAX_CARRY 8
|
||||
#define M203_GRENADE_MAX_CARRY 10
|
||||
#define AP9_MAX_CARRY 200
|
||||
#define TAURUS_MAX_CARRY 80
|
||||
#define SNIPER_MAX_CARRY 50
|
||||
#define CHAINGUN_MAX_CARRY 200
|
||||
#define MEDKIT_MAX_CARRY 12
|
||||
|
||||
// the maximum amount of ammo each weapon's clip can hold
|
||||
#define WEAPON_NOCLIP -1
|
||||
|
@ -134,6 +162,11 @@ public:
|
|||
#define SATCHEL_MAX_CLIP WEAPON_NOCLIP
|
||||
#define TRIPMINE_MAX_CLIP WEAPON_NOCLIP
|
||||
#define SNARK_MAX_CLIP WEAPON_NOCLIP
|
||||
#define AP9_MAX_CLIP 40
|
||||
#define TAURUS_MAX_CLIP 10
|
||||
#define SNIPER_MAX_CLIP 5
|
||||
#define CHAINGUN_MAX_CLIP 100
|
||||
#define MEDKIT_MAX_CLIP WEAPON_NOCLIP
|
||||
|
||||
// the default amount of ammo that comes with each gun when it spawns
|
||||
#define GLOCK_DEFAULT_GIVE 17
|
||||
|
@ -151,6 +184,11 @@ public:
|
|||
#define TRIPMINE_DEFAULT_GIVE 1
|
||||
#define SNARK_DEFAULT_GIVE 5
|
||||
#define HIVEHAND_DEFAULT_GIVE 8
|
||||
#define AP9_DEFAULT_GIVE 40
|
||||
#define TAURUS_DEFAULT_GIVE 10
|
||||
#define SNIPER_DEFAULT_GIVE 5
|
||||
#define CHAINGUN_DEFAULT_GIVE 100
|
||||
#define MEDKIT_DEFAULT_GIVE 12
|
||||
|
||||
// The amount of ammo given to a player by an ammo item.
|
||||
#define AMMO_URANIUMBOX_GIVE 20
|
||||
|
@ -164,6 +202,10 @@ public:
|
|||
#define AMMO_RPGCLIP_GIVE RPG_MAX_CLIP
|
||||
#define AMMO_URANIUMBOX_GIVE 20
|
||||
#define AMMO_SNARKBOX_GIVE 5
|
||||
#define AMMO_AP9_GIVE AP9_MAX_CLIP
|
||||
#define AMMO_TAURUS_GIVE TAURUS_MAX_CLIP
|
||||
#define AMMO_SNIPER_GIVE SNIPER_MAX_CLIP
|
||||
#define AMMO_CHAINGUN_GIVE CHAINGUN_MAX_CLIP
|
||||
|
||||
// bullet types
|
||||
typedef enum
|
||||
|
@ -174,7 +216,10 @@ typedef enum
|
|||
BULLET_PLAYER_357, // python
|
||||
BULLET_PLAYER_BUCKSHOT, // shotgun
|
||||
BULLET_PLAYER_CROWBAR, // crowbar swipe
|
||||
|
||||
BULLET_PLAYER_AP9,
|
||||
BULLET_PLAYER_CHAINGUN,
|
||||
BULLET_PLAYER_SNIPER,
|
||||
BULLET_PLAYER_TAURUS,
|
||||
BULLET_MONSTER_9MM,
|
||||
BULLET_MONSTER_MP5,
|
||||
BULLET_MONSTER_12MM
|
||||
|
@ -331,6 +376,7 @@ public:
|
|||
void PrintState( void );
|
||||
|
||||
virtual CBasePlayerItem *GetWeaponPtr( void ) { return (CBasePlayerItem *)this; };
|
||||
float GetNextAttackDelay( float delay );
|
||||
|
||||
float m_flPumpTime;
|
||||
int m_fInSpecialReload; // Are we in the middle of a reload for the shotguns
|
||||
|
@ -345,6 +391,10 @@ public:
|
|||
int m_fInReload; // Are we in the middle of a reload;
|
||||
|
||||
int m_iDefaultAmmo;// how much ammo you get when you pick up this weapon as placed by a level designer.
|
||||
|
||||
// hle time creep vars
|
||||
float m_flPrevPrimaryAttack;
|
||||
float m_flLastFireTime;
|
||||
};
|
||||
|
||||
class CBasePlayerAmmo : public CBaseEntity
|
||||
|
@ -368,6 +418,7 @@ extern DLL_GLOBAL short g_sModelIndexWExplosion;// holds the index for the under
|
|||
extern DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model
|
||||
extern DLL_GLOBAL short g_sModelIndexBloodDrop;// holds the sprite index for blood drops
|
||||
extern DLL_GLOBAL short g_sModelIndexBloodSpray;// holds the sprite index for blood spray (bigger)
|
||||
extern DLL_GLOBAL short g_sModelIndexFThrow;// holds the index for the flamethrower
|
||||
|
||||
extern void ClearMultiDamage(void);
|
||||
extern void ApplyMultiDamage(entvars_t* pevInflictor, entvars_t* pevAttacker );
|
||||
|
@ -475,6 +526,16 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
void Holster( int skiplocal = 0 );
|
||||
BOOL ShouldWeaponIdle( void );
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
int Save( CSave &save );
|
||||
int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
#endif
|
||||
|
||||
BOOL m_fSilencerOn;
|
||||
private:
|
||||
int m_iShell;
|
||||
|
||||
|
@ -525,6 +586,11 @@ public:
|
|||
void Holster( int skiplocal = 0 );
|
||||
void Reload( void );
|
||||
void WeaponIdle( void );
|
||||
#ifndef CLIENT_DLL
|
||||
int Save( CSave &save );
|
||||
int Restore( CRestore &restore );
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
#endif
|
||||
float m_flSoundDelay;
|
||||
|
||||
BOOL m_fInZoom;// don't save this.
|
||||
|
@ -982,4 +1048,298 @@ public:
|
|||
private:
|
||||
unsigned short m_usSnarkFire;
|
||||
};
|
||||
|
||||
class CShovel : public CCrowbar
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
|
||||
void PrimaryAttack( void );
|
||||
int Swing( int fFirst );
|
||||
BOOL Deploy( void );
|
||||
void Holster( int skiplocal = 0 );
|
||||
private:
|
||||
unsigned short m_usShovel;
|
||||
};
|
||||
|
||||
class CSpanner : public CCrowbar
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
|
||||
void PrimaryAttack(void);
|
||||
int Swing(int fFirst);
|
||||
BOOL Deploy(void);
|
||||
void Holster(int skiplocal = 0);
|
||||
|
||||
private:
|
||||
unsigned short m_usSpanner;
|
||||
};
|
||||
|
||||
class CAP9 : public CBasePlayerWeapon
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
int Save(CSave &save);
|
||||
int Restore(CRestore &restore);
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
#endif
|
||||
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
int iItemSlot(void) { return 2; }
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
int AddToPlayer(CBasePlayer *pPlayer);
|
||||
|
||||
void PrimaryAttack(void);
|
||||
void SecondaryAttack(void);
|
||||
void AP9Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim, BOOL fBurstShot);
|
||||
BOOL Deploy(void);
|
||||
void Reload(void);
|
||||
void WeaponIdle(void);
|
||||
BOOL ShouldWeaponIdle(void) { return TRUE; }
|
||||
int m_iShell;
|
||||
|
||||
virtual BOOL UseDecrement(void)
|
||||
{
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int m_iBurstShots;
|
||||
|
||||
private:
|
||||
unsigned short m_usFireAP9;
|
||||
};
|
||||
|
||||
class CTaurus : public CGlock
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
|
||||
void PrimaryAttack( void );
|
||||
void SecondaryAttack( void ) {}
|
||||
BOOL Deploy( void );
|
||||
void Reload( void );
|
||||
void WeaponIdle( void );
|
||||
private:
|
||||
int m_iShell;
|
||||
|
||||
unsigned short m_usFireTaurus;
|
||||
};
|
||||
|
||||
class CSniper : public CBasePlayerWeapon
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
int Save(CSave &save);
|
||||
int Restore(CRestore &restore);
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
#endif
|
||||
|
||||
virtual int GetPrimaryAttackActivity(void) = 0;
|
||||
virtual int GetZoomedAttackActivity(void) = 0;
|
||||
|
||||
int iItemSlot(void) { return 3; }
|
||||
int AddToPlayer(CBasePlayer *pPlayer);
|
||||
void PrimaryAttack(void);
|
||||
void SecondaryAttack(void);
|
||||
void SniperFire(float flSpread, float flCycleTime, BOOL fUseAutoAim, int iActivity);
|
||||
void Holster(int skiplocal = 0);
|
||||
void Reload(void);
|
||||
void WeaponIdle(void);
|
||||
|
||||
virtual BOOL UseDecrement(void)
|
||||
{
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetZoomState(BOOL bState);
|
||||
void ToggleZoom(void);
|
||||
|
||||
BOOL m_fInZoom;
|
||||
|
||||
protected:
|
||||
unsigned short m_usFireSniper;
|
||||
};
|
||||
|
||||
class CHKG36 : public CSniper
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
BOOL Deploy(void);
|
||||
void Reload(void);
|
||||
void WeaponIdle(void);
|
||||
|
||||
int GetPrimaryAttackActivity(void);
|
||||
int GetZoomedAttackActivity(void);
|
||||
};
|
||||
|
||||
#if 0
|
||||
class CEinar1 : public CSniper
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
void PrimaryAttack(void);
|
||||
void SecondaryAttack(void);
|
||||
BOOL Deploy(void);
|
||||
void Holster(int skiplocal = 0);
|
||||
void Reload(void);
|
||||
void WeaponIdle(void);
|
||||
BOOL ShouldWeaponIdle(void);
|
||||
int GetPrimaryAttackActivity(void);
|
||||
int GetZoomedAttackActivity(void);
|
||||
private:
|
||||
unsigned short m_usFireSniper2;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
class CEinar1 : public CBasePlayerWeapon
|
||||
{
|
||||
public:
|
||||
#ifndef CLIENT_DLL
|
||||
int Save(CSave &save);
|
||||
int Restore(CRestore &restore);
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
#endif
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
int iItemSlot(void) { return 3; }
|
||||
int AddToPlayer(CBasePlayer *pPlayer);
|
||||
void PrimaryAttack(void);
|
||||
void SecondaryAttack(void);
|
||||
BOOL Deploy(void);
|
||||
void Holster(int skiplocal = 0);
|
||||
void Reload(void);
|
||||
void WeaponIdle(void);
|
||||
BOOL ShouldWeaponIdle(void);
|
||||
virtual BOOL UseDecrement(void)
|
||||
{
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
void SetZoomState(BOOL bState);
|
||||
void ToggleZoom(void);
|
||||
BOOL m_fInZoom;
|
||||
private:
|
||||
unsigned short m_usFireSniper;
|
||||
unsigned short m_usFireSniper2;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
class CEinar1 : public CSniper
|
||||
{
|
||||
public:
|
||||
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
void PrimaryAttack(void);
|
||||
void SecondaryAttack(void);
|
||||
BOOL Deploy(void);
|
||||
void Holster(int skiplocal = 0);
|
||||
void Reload(void);
|
||||
void WeaponIdle(void);
|
||||
BOOL ShouldWeaponIdle(void);
|
||||
|
||||
int GetPrimaryAttackActivity(void);
|
||||
int GetZoomedAttackActivity(void);
|
||||
};
|
||||
#endif
|
||||
|
||||
class CChaingun : public CBasePlayerWeapon
|
||||
{
|
||||
public:
|
||||
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
int iItemSlot(void) { return 4; }
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
|
||||
void PrimaryAttack(void);
|
||||
void SecondaryAttack(void);
|
||||
BOOL Deploy(void);
|
||||
void Holster(int skiplocal = 0);
|
||||
void Reload(void);
|
||||
void WeaponIdle(void);
|
||||
BOOL ShouldWeaponIdle(void);
|
||||
|
||||
virtual BOOL UseDecrement(void)
|
||||
{
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SpinUp(void);
|
||||
void SpinDown(void);
|
||||
void Spin(void);
|
||||
void Fire(float flSpread, float flCycleTime, BOOL fUseAutoAim);
|
||||
|
||||
void StopSounds(void);
|
||||
|
||||
private:
|
||||
int m_iShell;
|
||||
|
||||
unsigned short m_usFireChaingun1;
|
||||
unsigned short m_usFireChaingun2;
|
||||
};
|
||||
|
||||
class CMedkit : public CBasePlayerWeapon
|
||||
{
|
||||
public:
|
||||
void Spawn(void);
|
||||
void Precache(void);
|
||||
int iItemSlot(void) { return 5; }
|
||||
int GetItemInfo(ItemInfo *p);
|
||||
|
||||
void PrimaryAttack(void);
|
||||
BOOL Deploy(void);
|
||||
void Holster(int skiplocal = 0);
|
||||
void WeaponIdle(void);
|
||||
BOOL PlayEmptySound(void);
|
||||
BOOL ShouldWeaponIdle(void) { return TRUE; }
|
||||
|
||||
virtual BOOL UseDecrement(void)
|
||||
{
|
||||
#if defined( CLIENT_WEAPONS )
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
float m_flSoundDelay;
|
||||
|
||||
private:
|
||||
|
||||
unsigned short m_usMedkit;
|
||||
};
|
||||
#endif // WEAPONS_H
|
||||
|
|
|
@ -617,20 +617,6 @@ void CWorld::Precache( void )
|
|||
// g-cont. moved here to right restore global WaveHeight on save\restore level
|
||||
CVAR_SET_FLOAT( "sv_wateramp", pev->scale );
|
||||
|
||||
if( pev->netname )
|
||||
{
|
||||
ALERT( at_aiconsole, "Chapter title: %s\n", STRING( pev->netname ) );
|
||||
CBaseEntity *pEntity = CBaseEntity::Create( "env_message", g_vecZero, g_vecZero, NULL );
|
||||
if( pEntity )
|
||||
{
|
||||
pEntity->SetThink( &CBaseEntity::SUB_CallUseToggle );
|
||||
pEntity->pev->message = pev->netname;
|
||||
pev->netname = 0;
|
||||
pEntity->pev->nextthink = gpGlobals->time + 0.3;
|
||||
pEntity->pev->spawnflags = SF_MESSAGE_ONCE;
|
||||
}
|
||||
}
|
||||
|
||||
if( pev->spawnflags & SF_WORLD_DARK )
|
||||
CVAR_SET_FLOAT( "v_dark", 1.0 );
|
||||
else
|
||||
|
|
466
dlls/zombie.cpp
466
dlls/zombie.cpp
|
@ -23,6 +23,58 @@
|
|||
#include "cbase.h"
|
||||
#include "monsters.h"
|
||||
#include "schedule.h"
|
||||
#include "zombie.h"
|
||||
|
||||
//
|
||||
// Spawn Flags
|
||||
//
|
||||
#define SF_ZOMBIE_FASTMODE 1024
|
||||
|
||||
#define NUM_ZOMBIE1_BODIES 11
|
||||
#define NUM_ZOMBIE2_BODIES 6
|
||||
#define NUM_ZOMBIE3_BODIES 5
|
||||
|
||||
enum
|
||||
{
|
||||
ZOMBIE1_FUNERAL = 0,
|
||||
ZOMBIE1_FUNERAL_HEADLESS,
|
||||
ZOMBIE1_CIVILIAN,
|
||||
ZOMBIE1_CIVILIAN_HEADLESS,
|
||||
ZOMBIE1_COP,
|
||||
ZOMBIE1_FEMALE,
|
||||
ZOMBIE1_BIOHAZARD_SUIT,
|
||||
ZOMBIE1_ECHELON_OFFICER,
|
||||
ZOMBIE1_EINSTEIN,
|
||||
ZOMBIE1_DOCTOR,
|
||||
ZOMBIE1_PATIENT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ZOMBIE2_COP_HEADOPEN = 0,
|
||||
ZOMBIE2_COP_CROWBAR,
|
||||
ZOMBIE2_DOCTOR,
|
||||
ZOMBIE2_DOCTOR_BUTCHER,
|
||||
ZOMBIE2_DOCTOR_SHOTGUN,
|
||||
ZOMBIE2_CIVILIAN_CHEST_GUN
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ZOMBIE3_NEIL = 0,
|
||||
ZOMBIE3_BROOM,
|
||||
ZOMBIE3_OLD,
|
||||
ZOMBIE3_MECHANIC,
|
||||
ZOMBIE3_HAMMER
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LPZOMBIE_STANDARD = 0,
|
||||
LPZOMBIE_COP,
|
||||
LPZOMBIE_BURNT,
|
||||
LPZOMBIE_FLESH
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Monster's Anim Events Go Here
|
||||
|
@ -33,37 +85,14 @@
|
|||
|
||||
#define ZOMBIE_FLINCH_DELAY 2 // at most one flinch every n secs
|
||||
|
||||
class CZombie : public CBaseMonster
|
||||
LINK_ENTITY_TO_CLASS( monster_zombie, CZombie )
|
||||
|
||||
TYPEDESCRIPTION CZombie::m_SaveData[] =
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void SetYawSpeed( void );
|
||||
int Classify( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
int IgnoreConditions( void );
|
||||
|
||||
float m_flNextFlinch;
|
||||
|
||||
void PainSound( void );
|
||||
void AlertSound( void );
|
||||
void IdleSound( void );
|
||||
void AttackSound( void );
|
||||
|
||||
static const char *pAttackSounds[];
|
||||
static const char *pIdleSounds[];
|
||||
static const char *pAlertSounds[];
|
||||
static const char *pPainSounds[];
|
||||
static const char *pAttackHitSounds[];
|
||||
static const char *pAttackMissSounds[];
|
||||
|
||||
// No range attacks
|
||||
BOOL CheckRangeAttack1( float flDot, float flDist ) { return FALSE; }
|
||||
BOOL CheckRangeAttack2( float flDot, float flDist ) { return FALSE; }
|
||||
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
|
||||
DEFINE_FIELD( CZombie, m_iZombieFlags, FIELD_INTEGER ),
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( monster_zombie, CZombie )
|
||||
IMPLEMENT_SAVERESTORE( CZombie, CBaseMonster )
|
||||
|
||||
const char *CZombie::pAttackHitSounds[] =
|
||||
{
|
||||
|
@ -105,6 +134,135 @@ const char *CZombie::pPainSounds[] =
|
|||
"zombie/zo_pain2.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pCopAttackSounds[] =
|
||||
{
|
||||
"zombiecop/zo_attack1.wav",
|
||||
"zombiecop/zo_attack2.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pCopIdleSounds[] =
|
||||
{
|
||||
"zombiecop/zo_idle1.wav",
|
||||
"zombiecop/zo_idle2.wav",
|
||||
"zombiecop/zo_idle3.wav",
|
||||
"zombiecop/zo_idle4.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pCopAlertSounds[] =
|
||||
{
|
||||
"zombiecop/zo_alert10.wav",
|
||||
"zombiecop/zo_alert20.wav",
|
||||
"zombiecop/zo_alert30.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pCopPainSounds[] =
|
||||
{
|
||||
"zombiecop/zo_pain1.wav",
|
||||
"zombiecop/zo_pain2.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pFemaleAttackSounds[] =
|
||||
{
|
||||
"zfemale/zo_attack1.wav",
|
||||
"zfemale/zo_attack2.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pFemaleIdleSounds[] =
|
||||
{
|
||||
"zfemale/zo_idle1.wav",
|
||||
"zfemale/zo_idle2.wav",
|
||||
"zfemale/zo_idle3.wav",
|
||||
"zfemale/zo_idle4.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pFemaleAlertSounds[] =
|
||||
{
|
||||
"zfemale/zo_alert10.wav",
|
||||
"zfemale/zo_alert20.wav",
|
||||
"zfemale/zo_alert30.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pFemalePainSounds[] =
|
||||
{
|
||||
"zfemale/zo_pain1.wav",
|
||||
"zfemale/zo_pain2.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pNurseAttackSounds[] =
|
||||
{
|
||||
"znurse/zo_attack1.wav",
|
||||
"znurse/zo_attack2.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pNurseIdleSounds[] =
|
||||
{
|
||||
"znurse/zo_idle1.wav",
|
||||
"znurse/zo_idle2.wav",
|
||||
"znurse/zo_idle3.wav",
|
||||
"znurse/zo_idle4.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pNurseAlertSounds[] =
|
||||
{
|
||||
"znurse/zo_alert10.wav",
|
||||
"znurse/zo_alert20.wav",
|
||||
"znurse/zo_alert30.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pNursePainSounds[] =
|
||||
{
|
||||
"znurse/zo_pain1.wav",
|
||||
"znurse/zo_pain2.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pNewAttackSounds[] =
|
||||
{
|
||||
"zombienew/zo_attack1.wav",
|
||||
"zombienew/zo_attack2.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pNewIdleSounds[] =
|
||||
{
|
||||
"zombienew/zo_idle1.wav",
|
||||
"zombienew/zo_idle2.wav",
|
||||
"zombienew/zo_idle3.wav",
|
||||
"zombienew/zo_idle4.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pNewAlertSounds[] =
|
||||
{
|
||||
"zombienew/zo_alert10.wav",
|
||||
"zombienew/zo_alert20.wav",
|
||||
"zombienew/zo_alert30.wav",
|
||||
};
|
||||
|
||||
const char *CZombie::pNewPainSounds[] =
|
||||
{
|
||||
"zombienew/zo_pain1.wav",
|
||||
"zombienew/zo_pain2.wav",
|
||||
"zombienew/zo_pain3.wav",
|
||||
};
|
||||
|
||||
BOOL CZombie::IsFemale() const
|
||||
{
|
||||
return ( m_iZombieFlags & ZF_FEMALE );
|
||||
}
|
||||
|
||||
BOOL CZombie::IsNurse() const
|
||||
{
|
||||
return ( m_iZombieFlags & ZF_NURSE );
|
||||
}
|
||||
|
||||
BOOL CZombie::IsCop() const
|
||||
{
|
||||
return ( m_iZombieFlags & ZF_COP );
|
||||
}
|
||||
|
||||
BOOL CZombie::UseNewSounds() const
|
||||
{
|
||||
return ( m_iZombieFlags & ZF_NEWSOUNDS );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Classify - indicates this monster's place in the
|
||||
// relationship table.
|
||||
|
@ -151,31 +309,146 @@ int CZombie::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float
|
|||
|
||||
void CZombie::PainSound( void )
|
||||
{
|
||||
int pitch = 95 + RANDOM_LONG( 0, 9 );
|
||||
|
||||
if( RANDOM_LONG( 0, 5 ) < 2 )
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pPainSounds[RANDOM_LONG( 0, ARRAYSIZE( pPainSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
{
|
||||
int pitch = 95 + RANDOM_LONG( 0, 9 );
|
||||
|
||||
if( IsFemale() )
|
||||
{
|
||||
if( IsNurse() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pNursePainSounds[RANDOM_LONG( 0, ARRAYSIZE( pNursePainSounds) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pFemalePainSounds[RANDOM_LONG( 0, ARRAYSIZE( pFemalePainSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( IsCop() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pCopPainSounds[RANDOM_LONG( 0, ARRAYSIZE( pCopPainSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( UseNewSounds() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pNewPainSounds[RANDOM_LONG( 0, ARRAYSIZE( pNewPainSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pPainSounds[RANDOM_LONG( 0, ARRAYSIZE( pPainSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CZombie::AlertSound( void )
|
||||
{
|
||||
int pitch = 95 + RANDOM_LONG( 0, 9 );
|
||||
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pAlertSounds[ RANDOM_LONG( 0, ARRAYSIZE( pAlertSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
if( IsFemale() )
|
||||
{
|
||||
if( IsNurse() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pNurseAlertSounds[RANDOM_LONG( 0, ARRAYSIZE( pNurseAlertSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pFemaleAlertSounds[RANDOM_LONG( 0, ARRAYSIZE( pFemaleAlertSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( IsCop() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pCopAlertSounds[RANDOM_LONG(0, ARRAYSIZE(pCopAlertSounds) - 1)], 1.0, ATTN_NORM, 0, pitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( UseNewSounds() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pNewAlertSounds[RANDOM_LONG( 0, ARRAYSIZE( pNewAlertSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pAlertSounds[RANDOM_LONG( 0, ARRAYSIZE( pAlertSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CZombie::IdleSound( void )
|
||||
{
|
||||
int pitch = 95 + RANDOM_LONG( 0, 9 );
|
||||
|
||||
// Play a random idle sound
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pIdleSounds[RANDOM_LONG( 0, ARRAYSIZE( pIdleSounds ) -1 )], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG( -5, 5 ) );
|
||||
if( IsFemale() )
|
||||
{
|
||||
if( IsNurse() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pNurseIdleSounds[RANDOM_LONG( 0, ARRAYSIZE( pNurseIdleSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pFemaleIdleSounds[RANDOM_LONG( 0, ARRAYSIZE( pFemaleIdleSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( IsCop() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pCopIdleSounds[RANDOM_LONG(0, ARRAYSIZE(pCopIdleSounds) - 1)], 1.0, ATTN_NORM, 0, pitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( UseNewSounds() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pNewIdleSounds[RANDOM_LONG( 0, ARRAYSIZE( pNewIdleSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pIdleSounds[RANDOM_LONG( 0, ARRAYSIZE( pIdleSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CZombie::AttackSound( void )
|
||||
{
|
||||
int pitch = 100 + RANDOM_LONG( -5, 5 );
|
||||
|
||||
// Play a random attack sound
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pAttackSounds[RANDOM_LONG( 0, ARRAYSIZE( pAttackSounds ) - 1 )], 1.0, ATTN_NORM, 0, 100 + RANDOM_LONG( -5, 5 ) );
|
||||
if( IsFemale() )
|
||||
{
|
||||
if( IsNurse() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pNurseAttackSounds[RANDOM_LONG( 0, ARRAYSIZE( pNurseAttackSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pFemaleAttackSounds[RANDOM_LONG( 0, ARRAYSIZE( pFemaleAttackSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( IsCop() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pCopAttackSounds[RANDOM_LONG( 0, ARRAYSIZE( pCopAttackSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( UseNewSounds() )
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pNewAttackSounds[RANDOM_LONG( 0, ARRAYSIZE( pNewAttackSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
else
|
||||
{
|
||||
EMIT_SOUND_DYN( ENT( pev ), CHAN_VOICE, pAttackSounds[RANDOM_LONG( 0, ARRAYSIZE( pAttackSounds ) - 1 )], 1.0, ATTN_NORM, 0, pitch );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
@ -264,12 +537,19 @@ void CZombie::Spawn()
|
|||
{
|
||||
Precache();
|
||||
|
||||
SET_MODEL( ENT(pev), "models/zombie.mdl" );
|
||||
char* szModel = (char*)STRING( pev->model );
|
||||
if( !szModel || !*szModel )
|
||||
{
|
||||
szModel = "models/zombie.mdl";
|
||||
pev->model = ALLOC_STRING( szModel );
|
||||
}
|
||||
|
||||
SET_MODEL( ENT( pev ), STRING( pev->model ) );
|
||||
UTIL_SetSize( pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX );
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
m_bloodColor = BLOOD_COLOR_GREEN;
|
||||
m_bloodColor = BLOOD_COLOR_RED;
|
||||
pev->health = gSkillData.zombieHealth;
|
||||
pev->view_ofs = VEC_VIEW;// position of the eyes relative to monster's origin.
|
||||
m_flFieldOfView = 0.5;// indicates the width of this monster's forward view cone ( as a dotproduct result )
|
||||
|
@ -277,6 +557,76 @@ void CZombie::Spawn()
|
|||
m_afCapability = bits_CAP_DOORS_GROUP;
|
||||
|
||||
MonsterInit();
|
||||
|
||||
m_iZombieFlags = 0;
|
||||
|
||||
if( FStrEq( STRING( pev->model ), "models/zombie.mdl" ) )
|
||||
{
|
||||
switch( pev->body )
|
||||
{
|
||||
case ZOMBIE1_COP:
|
||||
m_iZombieFlags |= ZF_COP;
|
||||
break;
|
||||
case ZOMBIE1_FEMALE:
|
||||
m_iZombieFlags |= ZF_FEMALE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( FStrEq( STRING( pev->model ), "models/zombie2.mdl" ) )
|
||||
{
|
||||
switch( pev->body )
|
||||
{
|
||||
case ZOMBIE2_COP_HEADOPEN:
|
||||
case ZOMBIE2_COP_CROWBAR:
|
||||
m_iZombieFlags |= ZF_COP;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( FStrEq( STRING( pev->model ), "models/zombie3.mdl" ) )
|
||||
{
|
||||
// Third zombie model always use new sounds.
|
||||
m_iZombieFlags |= ZF_NEWSOUNDS;
|
||||
|
||||
switch( pev->body )
|
||||
{
|
||||
case ZOMBIE3_BROOM:
|
||||
m_iZombieFlags |= ZF_FEMALE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( FStrEq( STRING( pev->model ), "models/nursezombie.mdl" ) )
|
||||
{
|
||||
m_iZombieFlags |= ( ZF_FEMALE | ZF_NURSE );
|
||||
}
|
||||
else if( FStrEq( STRING( pev->model ), "models/lpzombie.mdl" ) ) // Special zombie type with few polygons.
|
||||
{
|
||||
// Low polygon zombie model always use new sounds.
|
||||
m_iZombieFlags |= ZF_NEWSOUNDS;
|
||||
|
||||
switch( pev->skin )
|
||||
{
|
||||
case LPZOMBIE_COP:
|
||||
m_iZombieFlags |= ZF_COP;
|
||||
break;
|
||||
case LPZOMBIE_FLESH:
|
||||
// Unable to differentiate genders so set this flag randomly.
|
||||
if( RANDOM_LONG( 0, 1 ) )
|
||||
m_iZombieFlags |= ZF_FEMALE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ALERT( at_warning, "Unsupported zombie model %s\n", STRING( pev->model ) );
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
@ -287,6 +637,10 @@ void CZombie::Precache()
|
|||
int i;
|
||||
|
||||
PRECACHE_MODEL( "models/zombie.mdl" );
|
||||
PRECACHE_MODEL( "models/zombie2.mdl" );
|
||||
PRECACHE_MODEL( "models/zombie3.mdl" );
|
||||
PRECACHE_MODEL( "models/nursezombie.mdl" );
|
||||
PRECACHE_MODEL( "models/lpzombie.mdl" );
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( pAttackHitSounds ); i++ )
|
||||
PRECACHE_SOUND( (char *)pAttackHitSounds[i] );
|
||||
|
@ -305,6 +659,26 @@ void CZombie::Precache()
|
|||
|
||||
for( i = 0; i < ARRAYSIZE( pPainSounds ); i++ )
|
||||
PRECACHE_SOUND( (char *)pPainSounds[i] );
|
||||
|
||||
PRECACHE_SOUND_ARRAY( pCopAttackSounds );
|
||||
PRECACHE_SOUND_ARRAY( pCopIdleSounds );
|
||||
PRECACHE_SOUND_ARRAY( pCopAlertSounds );
|
||||
PRECACHE_SOUND_ARRAY( pCopPainSounds );
|
||||
|
||||
PRECACHE_SOUND_ARRAY( pFemaleAttackSounds );
|
||||
PRECACHE_SOUND_ARRAY( pFemaleIdleSounds );
|
||||
PRECACHE_SOUND_ARRAY( pFemaleAlertSounds );
|
||||
PRECACHE_SOUND_ARRAY( pFemalePainSounds );
|
||||
|
||||
PRECACHE_SOUND_ARRAY( pNurseAttackSounds );
|
||||
PRECACHE_SOUND_ARRAY( pNurseIdleSounds );
|
||||
PRECACHE_SOUND_ARRAY( pNurseAlertSounds );
|
||||
PRECACHE_SOUND_ARRAY( pNursePainSounds );
|
||||
|
||||
PRECACHE_SOUND_ARRAY( pNewAttackSounds );
|
||||
PRECACHE_SOUND_ARRAY( pNewIdleSounds );
|
||||
PRECACHE_SOUND_ARRAY( pNewAlertSounds );
|
||||
PRECACHE_SOUND_ARRAY( pNewPainSounds );
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
|
@ -334,3 +708,21 @@ int CZombie::IgnoreConditions( void )
|
|||
|
||||
return iIgnore;
|
||||
}
|
||||
|
||||
//========================================================
|
||||
// RunAI - overridden for zombie because there are things
|
||||
// that need to be checked every think.
|
||||
//========================================================
|
||||
void CZombie::RunAI( void )
|
||||
{
|
||||
// first, do base class stuff
|
||||
CBaseMonster::RunAI();
|
||||
|
||||
if( pev->spawnflags & SF_ZOMBIE_FASTMODE )
|
||||
{
|
||||
if( m_Activity == ACT_WALK || m_Activity == ACT_RUN )
|
||||
{
|
||||
pev->framerate = 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/***
|
||||
*
|
||||
* 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 ZOMBIE_H
|
||||
#define ZOMBIE_H
|
||||
|
||||
//
|
||||
// Zombie Flags
|
||||
//
|
||||
#define ZF_FEMALE 1
|
||||
#define ZF_NURSE 2
|
||||
#define ZF_COP 4
|
||||
#define ZF_NEWSOUNDS 8
|
||||
|
||||
class CZombie : public CBaseMonster
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
void Precache( void );
|
||||
void SetYawSpeed( void );
|
||||
int Classify ( void );
|
||||
void HandleAnimEvent( MonsterEvent_t *pEvent );
|
||||
int IgnoreConditions ( void );
|
||||
|
||||
float m_flNextFlinch;
|
||||
|
||||
void PainSound( void );
|
||||
void AlertSound( void );
|
||||
void IdleSound( void );
|
||||
void AttackSound( void );
|
||||
|
||||
static const char *pAttackSounds[];
|
||||
static const char *pIdleSounds[];
|
||||
static const char *pAlertSounds[];
|
||||
static const char *pPainSounds[];
|
||||
static const char *pAttackHitSounds[];
|
||||
static const char *pAttackMissSounds[];
|
||||
|
||||
// No range attacks
|
||||
BOOL CheckRangeAttack1 ( float flDot, float flDist ) { return FALSE; }
|
||||
BOOL CheckRangeAttack2 ( float flDot, float flDist ) { return FALSE; }
|
||||
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
|
||||
|
||||
int Save(CSave &save);
|
||||
int Restore(CRestore &restore);
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
|
||||
void RunAI(void);
|
||||
|
||||
BOOL IsFemale() const;
|
||||
BOOL IsNurse() const;
|
||||
BOOL IsCop() const;
|
||||
BOOL UseNewSounds() const;
|
||||
|
||||
static const char *pCopAttackSounds[];
|
||||
static const char *pCopIdleSounds[];
|
||||
static const char *pCopAlertSounds[];
|
||||
static const char *pCopPainSounds[];
|
||||
|
||||
static const char *pFemaleAttackSounds[];
|
||||
static const char *pFemaleIdleSounds[];
|
||||
static const char *pFemaleAlertSounds[];
|
||||
static const char *pFemalePainSounds[];
|
||||
|
||||
static const char *pNurseAttackSounds[];
|
||||
static const char *pNurseIdleSounds[];
|
||||
static const char *pNurseAlertSounds[];
|
||||
static const char *pNursePainSounds[];
|
||||
|
||||
static const char *pNewAttackSounds[];
|
||||
static const char *pNewIdleSounds[];
|
||||
static const char *pNewAlertSounds[];
|
||||
static const char *pNewPainSounds[];
|
||||
|
||||
int m_iZombieFlags;
|
||||
};
|
||||
#endif // ZOMBIE_H
|
Loading…
Reference in New Issue