started implementing SLAMs and removed \hl2mp\ folders which served no purpose

This commit is contained in:
Pinsplash 2024-04-07 11:45:49 -05:00
parent c43159535e
commit 2b3830826e
78 changed files with 754 additions and 23735 deletions

View File

@ -1,985 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Player for HL2.
//
//=============================================================================//
#include "cbase.h"
#include "vcollide_parse.h"
#include "c_hl2mp_player.h"
#include "view.h"
#include "takedamageinfo.h"
#include "hl2mp_gamerules.h"
#include "in_buttons.h"
#include "iviewrender_beams.h" // flashlight beam
#include "r_efx.h"
#include "dlight.h"
// Don't alias here
#if defined( CHL2MP_Player )
#undef CHL2MP_Player
#endif
LINK_ENTITY_TO_CLASS( player, C_HL2MP_Player );
IMPLEMENT_CLIENTCLASS_DT(C_HL2MP_Player, DT_HL2MP_Player, CHL2MP_Player)
RecvPropFloat( RECVINFO( m_angEyeAngles[0] ) ),
RecvPropFloat( RECVINFO( m_angEyeAngles[1] ) ),
RecvPropEHandle( RECVINFO( m_hRagdoll ) ),
RecvPropInt( RECVINFO( m_iSpawnInterpCounter ) ),
RecvPropInt( RECVINFO( m_iPlayerSoundType) ),
RecvPropBool( RECVINFO( m_fIsWalking ) ),
END_RECV_TABLE()
BEGIN_PREDICTION_DATA( C_HL2MP_Player )
DEFINE_PRED_FIELD( m_fIsWalking, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
END_PREDICTION_DATA()
#define HL2_WALK_SPEED 150
#define HL2_NORM_SPEED 190
#define HL2_SPRINT_SPEED 320
static ConVar cl_playermodel( "cl_playermodel", "none", FCVAR_USERINFO | FCVAR_ARCHIVE | FCVAR_SERVER_CAN_EXECUTE, "Default Player Model");
static ConVar cl_defaultweapon( "cl_defaultweapon", "weapon_physcannon", FCVAR_USERINFO | FCVAR_ARCHIVE, "Default Spawn Weapon");
void SpawnBlood (Vector vecSpot, const Vector &vecDir, int bloodColor, float flDamage);
C_HL2MP_Player::C_HL2MP_Player() : m_PlayerAnimState( this ), m_iv_angEyeAngles( "C_HL2MP_Player::m_iv_angEyeAngles" )
{
m_iIDEntIndex = 0;
m_iSpawnInterpCounterCache = 0;
m_angEyeAngles.Init();
AddVar( &m_angEyeAngles, &m_iv_angEyeAngles, LATCH_SIMULATION_VAR );
m_EntClientFlags |= ENTCLIENTFLAG_DONTUSEIK;
m_blinkTimer.Invalidate();
m_pFlashlightBeam = NULL;
}
C_HL2MP_Player::~C_HL2MP_Player( void )
{
ReleaseFlashlight();
}
int C_HL2MP_Player::GetIDTarget() const
{
return m_iIDEntIndex;
}
//-----------------------------------------------------------------------------
// Purpose: Update this client's target entity
//-----------------------------------------------------------------------------
void C_HL2MP_Player::UpdateIDTarget()
{
if ( !IsLocalPlayer() )
return;
// Clear old target and find a new one
m_iIDEntIndex = 0;
// don't show IDs in chase spec mode
if ( GetObserverMode() == OBS_MODE_CHASE ||
GetObserverMode() == OBS_MODE_DEATHCAM )
return;
trace_t tr;
Vector vecStart, vecEnd;
VectorMA( MainViewOrigin(), 1500, MainViewForward(), vecEnd );
VectorMA( MainViewOrigin(), 10, MainViewForward(), vecStart );
UTIL_TraceLine( vecStart, vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
if ( !tr.startsolid && tr.DidHitNonWorldEntity() )
{
C_BaseEntity *pEntity = tr.m_pEnt;
if ( pEntity && (pEntity != this) )
{
m_iIDEntIndex = pEntity->entindex();
}
}
}
void C_HL2MP_Player::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator )
{
Vector vecOrigin = ptr->endpos - vecDir * 4;
float flDistance = 0.0f;
if ( info.GetAttacker() )
{
flDistance = (ptr->endpos - info.GetAttacker()->GetAbsOrigin()).Length();
}
if ( m_takedamage )
{
AddMultiDamage( info, this );
int blood = BloodColor();
CBaseEntity *pAttacker = info.GetAttacker();
if ( pAttacker )
{
if ( HL2MPRules()->IsTeamplay() && pAttacker->InSameTeam( this ) == true )
return;
}
if ( blood != DONT_BLEED )
{
SpawnBlood( vecOrigin, vecDir, blood, flDistance );// a little surface blood.
TraceBleed( flDistance, vecDir, ptr, info.GetDamageType() );
}
}
}
C_HL2MP_Player* C_HL2MP_Player::GetLocalHL2MPPlayer()
{
return (C_HL2MP_Player*)C_BasePlayer::GetLocalPlayer();
}
void C_HL2MP_Player::Initialize( void )
{
m_headYawPoseParam = LookupPoseParameter( "head_yaw" );
GetPoseParameterRange( m_headYawPoseParam, m_headYawMin, m_headYawMax );
m_headPitchPoseParam = LookupPoseParameter( "head_pitch" );
GetPoseParameterRange( m_headPitchPoseParam, m_headPitchMin, m_headPitchMax );
CStudioHdr *hdr = GetModelPtr();
for ( int i = 0; i < hdr->GetNumPoseParameters() ; i++ )
{
SetPoseParameter( hdr, i, 0.0 );
}
}
CStudioHdr *C_HL2MP_Player::OnNewModel( void )
{
CStudioHdr *hdr = BaseClass::OnNewModel();
Initialize( );
return hdr;
}
//-----------------------------------------------------------------------------
/**
* Orient head and eyes towards m_lookAt.
*/
void C_HL2MP_Player::UpdateLookAt( void )
{
// head yaw
if (m_headYawPoseParam < 0 || m_headPitchPoseParam < 0)
return;
// orient eyes
m_viewtarget = m_vLookAtTarget;
// blinking
if (m_blinkTimer.IsElapsed())
{
m_blinktoggle = !m_blinktoggle;
m_blinkTimer.Start( RandomFloat( 1.5f, 4.0f ) );
}
// Figure out where we want to look in world space.
QAngle desiredAngles;
Vector to = m_vLookAtTarget - EyePosition();
VectorAngles( to, desiredAngles );
// Figure out where our body is facing in world space.
QAngle bodyAngles( 0, 0, 0 );
bodyAngles[YAW] = GetLocalAngles()[YAW];
float flBodyYawDiff = bodyAngles[YAW] - m_flLastBodyYaw;
m_flLastBodyYaw = bodyAngles[YAW];
// Set the head's yaw.
float desired = AngleNormalize( desiredAngles[YAW] - bodyAngles[YAW] );
desired = clamp( desired, m_headYawMin, m_headYawMax );
m_flCurrentHeadYaw = ApproachAngle( desired, m_flCurrentHeadYaw, 130 * gpGlobals->frametime );
// Counterrotate the head from the body rotation so it doesn't rotate past its target.
m_flCurrentHeadYaw = AngleNormalize( m_flCurrentHeadYaw - flBodyYawDiff );
desired = clamp( desired, m_headYawMin, m_headYawMax );
SetPoseParameter( m_headYawPoseParam, m_flCurrentHeadYaw );
// Set the head's yaw.
desired = AngleNormalize( desiredAngles[PITCH] );
desired = clamp( desired, m_headPitchMin, m_headPitchMax );
m_flCurrentHeadPitch = ApproachAngle( desired, m_flCurrentHeadPitch, 130 * gpGlobals->frametime );
m_flCurrentHeadPitch = AngleNormalize( m_flCurrentHeadPitch );
SetPoseParameter( m_headPitchPoseParam, m_flCurrentHeadPitch );
}
void C_HL2MP_Player::ClientThink( void )
{
bool bFoundViewTarget = false;
Vector vForward;
AngleVectors( GetLocalAngles(), &vForward );
for( int iClient = 1; iClient <= gpGlobals->maxClients; ++iClient )
{
CBaseEntity *pEnt = UTIL_PlayerByIndex( iClient );
if(!pEnt || !pEnt->IsPlayer())
continue;
if ( pEnt->entindex() == entindex() )
continue;
Vector vTargetOrigin = pEnt->GetAbsOrigin();
Vector vMyOrigin = GetAbsOrigin();
Vector vDir = vTargetOrigin - vMyOrigin;
if ( vDir.Length() > 128 )
continue;
VectorNormalize( vDir );
if ( DotProduct( vForward, vDir ) < 0.0f )
continue;
m_vLookAtTarget = pEnt->EyePosition();
bFoundViewTarget = true;
break;
}
if ( bFoundViewTarget == false )
{
m_vLookAtTarget = GetAbsOrigin() + vForward * 512;
}
UpdateIDTarget();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
int C_HL2MP_Player::DrawModel( int flags )
{
if ( !m_bReadyToDraw )
return 0;
return BaseClass::DrawModel(flags);
}
//-----------------------------------------------------------------------------
// Should this object receive shadows?
//-----------------------------------------------------------------------------
bool C_HL2MP_Player::ShouldReceiveProjectedTextures( int flags )
{
Assert( flags & SHADOW_FLAGS_PROJECTED_TEXTURE_TYPE_MASK );
if ( IsEffectActive( EF_NODRAW ) )
return false;
if( flags & SHADOW_FLAGS_FLASHLIGHT )
{
return true;
}
return BaseClass::ShouldReceiveProjectedTextures( flags );
}
void C_HL2MP_Player::DoImpactEffect( trace_t &tr, int nDamageType )
{
if ( GetActiveWeapon() )
{
GetActiveWeapon()->DoImpactEffect( tr, nDamageType );
return;
}
BaseClass::DoImpactEffect( tr, nDamageType );
}
void C_HL2MP_Player::PreThink( void )
{
QAngle vTempAngles = GetLocalAngles();
if ( GetLocalPlayer() == this )
{
vTempAngles[PITCH] = EyeAngles()[PITCH];
}
else
{
vTempAngles[PITCH] = m_angEyeAngles[PITCH];
}
if ( vTempAngles[YAW] < 0.0f )
{
vTempAngles[YAW] += 360.0f;
}
SetLocalAngles( vTempAngles );
BaseClass::PreThink();
HandleSpeedChanges();
if ( m_HL2Local.m_flSuitPower <= 0.0f )
{
if( IsSprinting() )
{
StopSprinting();
}
}
}
const QAngle &C_HL2MP_Player::EyeAngles()
{
if( IsLocalPlayer() )
{
return BaseClass::EyeAngles();
}
else
{
return m_angEyeAngles;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_HL2MP_Player::AddEntity( void )
{
BaseClass::AddEntity();
QAngle vTempAngles = GetLocalAngles();
vTempAngles[PITCH] = m_angEyeAngles[PITCH];
SetLocalAngles( vTempAngles );
m_PlayerAnimState.Update();
// Zero out model pitch, blending takes care of all of it.
SetLocalAnglesDim( X_INDEX, 0 );
if( this != C_BasePlayer::GetLocalPlayer() )
{
if ( IsEffectActive( EF_DIMLIGHT ) )
{
int iAttachment = LookupAttachment( "anim_attachment_RH" );
if ( iAttachment < 0 )
return;
Vector vecOrigin;
QAngle eyeAngles = m_angEyeAngles;
GetAttachment( iAttachment, vecOrigin, eyeAngles );
Vector vForward;
AngleVectors( eyeAngles, &vForward );
trace_t tr;
UTIL_TraceLine( vecOrigin, vecOrigin + (vForward * 200), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
if( !m_pFlashlightBeam )
{
BeamInfo_t beamInfo;
beamInfo.m_nType = TE_BEAMPOINTS;
beamInfo.m_vecStart = tr.startpos;
beamInfo.m_vecEnd = tr.endpos;
beamInfo.m_pszModelName = "sprites/glow01.vmt";
beamInfo.m_pszHaloName = "sprites/glow01.vmt";
beamInfo.m_flHaloScale = 3.0;
beamInfo.m_flWidth = 8.0f;
beamInfo.m_flEndWidth = 35.0f;
beamInfo.m_flFadeLength = 300.0f;
beamInfo.m_flAmplitude = 0;
beamInfo.m_flBrightness = 60.0;
beamInfo.m_flSpeed = 0.0f;
beamInfo.m_nStartFrame = 0.0;
beamInfo.m_flFrameRate = 0.0;
beamInfo.m_flRed = 255.0;
beamInfo.m_flGreen = 255.0;
beamInfo.m_flBlue = 255.0;
beamInfo.m_nSegments = 8;
beamInfo.m_bRenderable = true;
beamInfo.m_flLife = 0.5;
beamInfo.m_nFlags = FBEAM_FOREVER | FBEAM_ONLYNOISEONCE | FBEAM_NOTILE | FBEAM_HALOBEAM;
m_pFlashlightBeam = beams->CreateBeamPoints( beamInfo );
}
if( m_pFlashlightBeam )
{
BeamInfo_t beamInfo;
beamInfo.m_vecStart = tr.startpos;
beamInfo.m_vecEnd = tr.endpos;
beamInfo.m_flRed = 255.0;
beamInfo.m_flGreen = 255.0;
beamInfo.m_flBlue = 255.0;
beams->UpdateBeamInfo( m_pFlashlightBeam, beamInfo );
dlight_t *el = effects->CL_AllocDlight( 0 );
el->origin = tr.endpos;
el->radius = 50;
el->color.r = 200;
el->color.g = 200;
el->color.b = 200;
el->die = gpGlobals->curtime + 0.1;
}
}
else if ( m_pFlashlightBeam )
{
ReleaseFlashlight();
}
}
}
ShadowType_t C_HL2MP_Player::ShadowCastType( void )
{
if ( !IsVisible() )
return SHADOWS_NONE;
return SHADOWS_RENDER_TO_TEXTURE_DYNAMIC;
}
const QAngle& C_HL2MP_Player::GetRenderAngles()
{
if ( IsRagdoll() )
{
return vec3_angle;
}
else
{
return m_PlayerAnimState.GetRenderAngles();
}
}
bool C_HL2MP_Player::ShouldDraw( void )
{
// If we're dead, our ragdoll will be drawn for us instead.
if ( !IsAlive() )
return false;
// if( GetTeamNumber() == TEAM_SPECTATOR )
// return false;
if( IsLocalPlayer() && IsRagdoll() )
return true;
if ( IsRagdoll() )
return false;
return BaseClass::ShouldDraw();
}
void C_HL2MP_Player::NotifyShouldTransmit( ShouldTransmitState_t state )
{
if ( state == SHOULDTRANSMIT_END )
{
if( m_pFlashlightBeam != NULL )
{
ReleaseFlashlight();
}
}
BaseClass::NotifyShouldTransmit( state );
}
void C_HL2MP_Player::OnDataChanged( DataUpdateType_t type )
{
BaseClass::OnDataChanged( type );
if ( type == DATA_UPDATE_CREATED )
{
SetNextClientThink( CLIENT_THINK_ALWAYS );
}
UpdateVisibility();
}
void C_HL2MP_Player::PostDataUpdate( DataUpdateType_t updateType )
{
if ( m_iSpawnInterpCounter != m_iSpawnInterpCounterCache )
{
MoveToLastReceivedPosition( true );
ResetLatched();
m_iSpawnInterpCounterCache = m_iSpawnInterpCounter;
}
BaseClass::PostDataUpdate( updateType );
}
void C_HL2MP_Player::ReleaseFlashlight( void )
{
if( m_pFlashlightBeam )
{
m_pFlashlightBeam->flags = 0;
m_pFlashlightBeam->die = gpGlobals->curtime - 1;
m_pFlashlightBeam = NULL;
}
}
float C_HL2MP_Player::GetFOV( void )
{
//Find our FOV with offset zoom value
float flFOVOffset = C_BasePlayer::GetFOV() + GetZoom();
// Clamp FOV in MP
int min_fov = GetMinFOV();
// Don't let it go too low
flFOVOffset = MAX( min_fov, flFOVOffset );
return flFOVOffset;
}
//=========================================================
// Autoaim
// set crosshair position to point to enemey
//=========================================================
Vector C_HL2MP_Player::GetAutoaimVector( float flDelta )
{
// Never autoaim a predicted weapon (for now)
Vector forward;
AngleVectors( EyeAngles() + m_Local.m_vecPunchAngle, &forward );
return forward;
}
//-----------------------------------------------------------------------------
// Purpose: Returns whether or not we are allowed to sprint now.
//-----------------------------------------------------------------------------
bool C_HL2MP_Player::CanSprint( void )
{
return ( (!m_Local.m_bDucked && !m_Local.m_bDucking) && (GetWaterLevel() != 3) );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void C_HL2MP_Player::StartSprinting( void )
{
if( m_HL2Local.m_flSuitPower < 10 )
{
// Don't sprint unless there's a reasonable
// amount of suit power.
CPASAttenuationFilter filter( this );
filter.UsePredictionRules();
EmitSound( filter, entindex(), "HL2Player.SprintNoPower" );
return;
}
CPASAttenuationFilter filter( this );
filter.UsePredictionRules();
EmitSound( filter, entindex(), "HL2Player.SprintStart" );
SetMaxSpeed( HL2_SPRINT_SPEED );
m_fIsSprinting = true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void C_HL2MP_Player::StopSprinting( void )
{
SetMaxSpeed( HL2_NORM_SPEED );
m_fIsSprinting = false;
}
void C_HL2MP_Player::HandleSpeedChanges( void )
{
int buttonsChanged = m_afButtonPressed | m_afButtonReleased;
if( buttonsChanged & IN_SPEED )
{
// The state of the sprint/run button has changed.
if ( IsSuitEquipped() )
{
if ( !(m_afButtonPressed & IN_SPEED) && IsSprinting() )
{
StopSprinting();
}
else if ( (m_afButtonPressed & IN_SPEED) && !IsSprinting() )
{
if ( CanSprint() )
{
StartSprinting();
}
else
{
// Reset key, so it will be activated post whatever is suppressing it.
m_nButtons &= ~IN_SPEED;
}
}
}
}
else if( buttonsChanged & IN_WALK )
{
if ( IsSuitEquipped() )
{
// The state of the WALK button has changed.
if( IsWalking() && !(m_afButtonPressed & IN_WALK) )
{
StopWalking();
}
else if( !IsWalking() && !IsSprinting() && (m_afButtonPressed & IN_WALK) && !(m_nButtons & IN_DUCK) )
{
StartWalking();
}
}
}
if ( IsSuitEquipped() && m_fIsWalking && !(m_nButtons & IN_WALK) )
StopWalking();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void C_HL2MP_Player::StartWalking( void )
{
SetMaxSpeed( HL2_WALK_SPEED );
m_fIsWalking = true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void C_HL2MP_Player::StopWalking( void )
{
SetMaxSpeed( HL2_NORM_SPEED );
m_fIsWalking = false;
}
void C_HL2MP_Player::ItemPreFrame( void )
{
if ( GetFlags() & FL_FROZEN )
return;
// Disallow shooting while zooming
if ( m_nButtons & IN_ZOOM )
{
//FIXME: Held weapons like the grenade get sad when this happens
m_nButtons &= ~(IN_ATTACK|IN_ATTACK2);
}
BaseClass::ItemPreFrame();
}
void C_HL2MP_Player::ItemPostFrame( void )
{
if ( GetFlags() & FL_FROZEN )
return;
BaseClass::ItemPostFrame();
}
C_BaseAnimating *C_HL2MP_Player::BecomeRagdollOnClient()
{
// Let the C_CSRagdoll entity do this.
// m_builtRagdoll = true;
return NULL;
}
void C_HL2MP_Player::CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov )
{
if ( m_lifeState != LIFE_ALIVE && !IsObserver() )
{
Vector origin = EyePosition();
IRagdoll *pRagdoll = GetRepresentativeRagdoll();
if ( pRagdoll )
{
origin = pRagdoll->GetRagdollOrigin();
origin.z += VEC_DEAD_VIEWHEIGHT_SCALED( this ).z; // look over ragdoll, not through
}
BaseClass::CalcView( eyeOrigin, eyeAngles, zNear, zFar, fov );
eyeOrigin = origin;
Vector vForward;
AngleVectors( eyeAngles, &vForward );
VectorNormalize( vForward );
VectorMA( origin, -CHASE_CAM_DISTANCE_MAX, vForward, eyeOrigin );
Vector WALL_MIN( -WALL_OFFSET, -WALL_OFFSET, -WALL_OFFSET );
Vector WALL_MAX( WALL_OFFSET, WALL_OFFSET, WALL_OFFSET );
trace_t trace; // clip against world
C_BaseEntity::PushEnableAbsRecomputations( false ); // HACK don't recompute positions while doing RayTrace
UTIL_TraceHull( origin, eyeOrigin, WALL_MIN, WALL_MAX, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trace );
C_BaseEntity::PopEnableAbsRecomputations();
if (trace.fraction < 1.0)
{
eyeOrigin = trace.endpos;
}
return;
}
BaseClass::CalcView( eyeOrigin, eyeAngles, zNear, zFar, fov );
}
IRagdoll* C_HL2MP_Player::GetRepresentativeRagdoll() const
{
if ( m_hRagdoll.Get() )
{
C_HL2MPRagdoll *pRagdoll = (C_HL2MPRagdoll*)m_hRagdoll.Get();
return pRagdoll->GetIRagdoll();
}
else
{
return NULL;
}
}
//HL2MPRAGDOLL
IMPLEMENT_CLIENTCLASS_DT_NOBASE( C_HL2MPRagdoll, DT_HL2MPRagdoll, CHL2MPRagdoll )
RecvPropVector( RECVINFO(m_vecRagdollOrigin) ),
RecvPropEHandle( RECVINFO( m_hPlayer ) ),
RecvPropInt( RECVINFO( m_nModelIndex ) ),
RecvPropInt( RECVINFO(m_nForceBone) ),
RecvPropVector( RECVINFO(m_vecForce) ),
RecvPropVector( RECVINFO( m_vecRagdollVelocity ) )
END_RECV_TABLE()
C_HL2MPRagdoll::C_HL2MPRagdoll()
{
}
C_HL2MPRagdoll::~C_HL2MPRagdoll()
{
PhysCleanupFrictionSounds( this );
if ( m_hPlayer )
{
m_hPlayer->CreateModelInstance();
}
}
void C_HL2MPRagdoll::Interp_Copy( C_BaseAnimatingOverlay *pSourceEntity )
{
if ( !pSourceEntity )
return;
VarMapping_t *pSrc = pSourceEntity->GetVarMapping();
VarMapping_t *pDest = GetVarMapping();
// Find all the VarMapEntry_t's that represent the same variable.
for ( int i = 0; i < pDest->m_Entries.Count(); i++ )
{
VarMapEntry_t *pDestEntry = &pDest->m_Entries[i];
const char *pszName = pDestEntry->watcher->GetDebugName();
for ( int j=0; j < pSrc->m_Entries.Count(); j++ )
{
VarMapEntry_t *pSrcEntry = &pSrc->m_Entries[j];
if ( !Q_strcmp( pSrcEntry->watcher->GetDebugName(), pszName ) )
{
pDestEntry->watcher->Copy( pSrcEntry->watcher );
break;
}
}
}
}
void C_HL2MPRagdoll::ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName )
{
IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
if( !pPhysicsObject )
return;
Vector dir = pTrace->endpos - pTrace->startpos;
if ( iDamageType == DMG_BLAST )
{
dir *= 4000; // adjust impact strenght
// apply force at object mass center
pPhysicsObject->ApplyForceCenter( dir );
}
else
{
Vector hitpos;
VectorMA( pTrace->startpos, pTrace->fraction, dir, hitpos );
VectorNormalize( dir );
dir *= 4000; // adjust impact strenght
// apply force where we hit it
pPhysicsObject->ApplyForceOffset( dir, hitpos );
// Blood spray!
// FX_CS_BloodSpray( hitpos, dir, 10 );
}
m_pRagdoll->ResetRagdollSleepAfterTime();
}
void C_HL2MPRagdoll::CreateHL2MPRagdoll( void )
{
// First, initialize all our data. If we have the player's entity on our client,
// then we can make ourselves start out exactly where the player is.
C_HL2MP_Player *pPlayer = dynamic_cast< C_HL2MP_Player* >( m_hPlayer.Get() );
if ( pPlayer && !pPlayer->IsDormant() )
{
// move my current model instance to the ragdoll's so decals are preserved.
pPlayer->SnatchModelInstance( this );
VarMapping_t *varMap = GetVarMapping();
// Copy all the interpolated vars from the player entity.
// The entity uses the interpolated history to get bone velocity.
bool bRemotePlayer = (pPlayer != C_BasePlayer::GetLocalPlayer());
if ( bRemotePlayer )
{
Interp_Copy( pPlayer );
SetAbsAngles( pPlayer->GetRenderAngles() );
GetRotationInterpolator().Reset();
m_flAnimTime = pPlayer->m_flAnimTime;
SetSequence( pPlayer->GetSequence() );
m_flPlaybackRate = pPlayer->GetPlaybackRate();
}
else
{
// This is the local player, so set them in a default
// pose and slam their velocity, angles and origin
SetAbsOrigin( m_vecRagdollOrigin );
SetAbsAngles( pPlayer->GetRenderAngles() );
SetAbsVelocity( m_vecRagdollVelocity );
int iSeq = pPlayer->GetSequence();
if ( iSeq == -1 )
{
Assert( false ); // missing walk_lower?
iSeq = 0;
}
SetSequence( iSeq ); // walk_lower, basic pose
SetCycle( 0.0 );
Interp_Reset( varMap );
}
}
else
{
// overwrite network origin so later interpolation will
// use this position
SetNetworkOrigin( m_vecRagdollOrigin );
SetAbsOrigin( m_vecRagdollOrigin );
SetAbsVelocity( m_vecRagdollVelocity );
Interp_Reset( GetVarMapping() );
}
SetModelIndex( m_nModelIndex );
// Make us a ragdoll..
m_nRenderFX = kRenderFxRagdoll;
matrix3x4_t boneDelta0[MAXSTUDIOBONES];
matrix3x4_t boneDelta1[MAXSTUDIOBONES];
matrix3x4_t currentBones[MAXSTUDIOBONES];
const float boneDt = 0.05f;
if ( pPlayer && !pPlayer->IsDormant() )
{
pPlayer->GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
}
else
{
GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt );
}
InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt );
}
void C_HL2MPRagdoll::OnDataChanged( DataUpdateType_t type )
{
BaseClass::OnDataChanged( type );
if ( type == DATA_UPDATE_CREATED )
{
CreateHL2MPRagdoll();
}
}
IRagdoll* C_HL2MPRagdoll::GetIRagdoll() const
{
return m_pRagdoll;
}
void C_HL2MPRagdoll::UpdateOnRemove( void )
{
VPhysicsSetObject( NULL );
BaseClass::UpdateOnRemove();
}
//-----------------------------------------------------------------------------
// Purpose: clear out any face/eye values stored in the material system
//-----------------------------------------------------------------------------
void C_HL2MPRagdoll::SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights )
{
BaseClass::SetupWeights( pBoneToWorld, nFlexWeightCount, pFlexWeights, pFlexDelayedWeights );
static float destweight[128];
static bool bIsInited = false;
CStudioHdr *hdr = GetModelPtr();
if ( !hdr )
return;
int nFlexDescCount = hdr->numflexdesc();
if ( nFlexDescCount )
{
Assert( !pFlexDelayedWeights );
memset( pFlexWeights, 0, nFlexWeightCount * sizeof(float) );
}
if ( m_iEyeAttachment > 0 )
{
matrix3x4_t attToWorld;
if (GetAttachment( m_iEyeAttachment, attToWorld ))
{
Vector local, tmp;
local.Init( 1000.0f, 0.0f, 0.0f );
VectorTransform( local, attToWorld, tmp );
modelrender->SetViewTarget( GetModelPtr(), GetBody(), tmp );
}
}
}
void C_HL2MP_Player::PostThink( void )
{
BaseClass::PostThink();
// Store the eye angles pitch so the client can compute its animation state correctly.
m_angEyeAngles = EyeAngles();
}

View File

@ -1,173 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef HL2MP_PLAYER_H
#define HL2MP_PLAYER_H
#pragma once
class C_HL2MP_Player;
#include "c_basehlplayer.h"
#include "hl2mp_player_shared.h"
#include "beamdraw.h"
//=============================================================================
// >> HL2MP_Player
//=============================================================================
class C_HL2MP_Player : public C_BaseHLPlayer
{
public:
DECLARE_CLASS( C_HL2MP_Player, C_BaseHLPlayer );
DECLARE_CLIENTCLASS();
DECLARE_PREDICTABLE();
DECLARE_INTERPOLATION();
C_HL2MP_Player();
~C_HL2MP_Player( void );
void ClientThink( void );
static C_HL2MP_Player* GetLocalHL2MPPlayer();
virtual int DrawModel( int flags );
virtual void AddEntity( void );
QAngle GetAnimEyeAngles( void ) { return m_angEyeAngles; }
Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL );
// Should this object cast shadows?
virtual ShadowType_t ShadowCastType( void );
virtual C_BaseAnimating *BecomeRagdollOnClient();
virtual const QAngle& GetRenderAngles();
virtual bool ShouldDraw( void );
virtual void OnDataChanged( DataUpdateType_t type );
virtual float GetFOV( void );
virtual CStudioHdr *OnNewModel( void );
virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
virtual void ItemPreFrame( void );
virtual void ItemPostFrame( void );
virtual float GetMinFOV() const { return 5.0f; }
virtual Vector GetAutoaimVector( float flDelta );
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
virtual void CreateLightEffects( void ) {}
virtual bool ShouldReceiveProjectedTextures( int flags );
virtual void PostDataUpdate( DataUpdateType_t updateType );
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
virtual void PreThink( void );
virtual void DoImpactEffect( trace_t &tr, int nDamageType );
IRagdoll* GetRepresentativeRagdoll() const;
virtual void CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov );
virtual const QAngle& EyeAngles( void );
bool CanSprint( void );
void StartSprinting( void );
void StopSprinting( void );
void HandleSpeedChanges( void );
void UpdateLookAt( void );
void Initialize( void );
int GetIDTarget() const;
void UpdateIDTarget( void );
void PrecacheFootStepSounds( void );
const char *GetPlayerModelSoundPrefix( void );
HL2MPPlayerState State_Get() const;
// Walking
void StartWalking( void );
void StopWalking( void );
bool IsWalking( void ) { return m_fIsWalking; }
virtual void PostThink( void );
private:
C_HL2MP_Player( const C_HL2MP_Player & );
CPlayerAnimState m_PlayerAnimState;
QAngle m_angEyeAngles;
CInterpolatedVar< QAngle > m_iv_angEyeAngles;
EHANDLE m_hRagdoll;
int m_headYawPoseParam;
int m_headPitchPoseParam;
float m_headYawMin;
float m_headYawMax;
float m_headPitchMin;
float m_headPitchMax;
bool m_isInit;
Vector m_vLookAtTarget;
float m_flLastBodyYaw;
float m_flCurrentHeadYaw;
float m_flCurrentHeadPitch;
int m_iIDEntIndex;
CountdownTimer m_blinkTimer;
int m_iSpawnInterpCounter;
int m_iSpawnInterpCounterCache;
int m_iPlayerSoundType;
void ReleaseFlashlight( void );
Beam_t *m_pFlashlightBeam;
CNetworkVar( HL2MPPlayerState, m_iPlayerState );
bool m_fIsWalking;
};
inline C_HL2MP_Player *ToHL2MPPlayer( CBaseEntity *pEntity )
{
if ( !pEntity || !pEntity->IsPlayer() )
return NULL;
return dynamic_cast<C_HL2MP_Player*>( pEntity );
}
class C_HL2MPRagdoll : public C_BaseAnimatingOverlay
{
public:
DECLARE_CLASS( C_HL2MPRagdoll, C_BaseAnimatingOverlay );
DECLARE_CLIENTCLASS();
C_HL2MPRagdoll();
~C_HL2MPRagdoll();
virtual void OnDataChanged( DataUpdateType_t type );
int GetPlayerEntIndex() const;
IRagdoll* GetIRagdoll() const;
void ImpactTrace( trace_t *pTrace, int iDamageType, const char *pCustomImpactName );
void UpdateOnRemove( void );
virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights );
private:
C_HL2MPRagdoll( const C_HL2MPRagdoll & ) {}
void Interp_Copy( C_BaseAnimatingOverlay *pDestinationEntity );
void CreateHL2MPRagdoll( void );
private:
EHANDLE m_hPlayer;
CNetworkVector( m_vecRagdollVelocity );
CNetworkVector( m_vecRagdollOrigin );
};
#endif //HL2MP_PLAYER_H

View File

@ -1,160 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "c_basetempentity.h"
#include <cliententitylist.h>
#include "ammodef.h"
#include "c_te_effect_dispatch.h"
#include "shot_manipulator.h"
class C_TEHL2MPFireBullets : public C_BaseTempEntity
{
public:
DECLARE_CLASS( C_TEHL2MPFireBullets, C_BaseTempEntity );
DECLARE_CLIENTCLASS();
virtual void PostDataUpdate( DataUpdateType_t updateType );
void CreateEffects( void );
public:
int m_iPlayer;
Vector m_vecOrigin;
Vector m_vecDir;
int m_iAmmoID;
int m_iWeaponIndex;
int m_iSeed;
float m_flSpread;
int m_iShots;
bool m_bDoImpacts;
bool m_bDoTracers;
};
class CTraceFilterSkipPlayerAndViewModelOnly : public CTraceFilter
{
public:
virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
{
C_BaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
if( pEntity &&
( ( dynamic_cast<C_BaseViewModel *>( pEntity ) != NULL ) ||
( dynamic_cast<C_BasePlayer *>( pEntity ) != NULL ) ) )
{
return false;
}
else
{
return true;
}
}
};
void C_TEHL2MPFireBullets::CreateEffects( void )
{
CAmmoDef* pAmmoDef = GetAmmoDef();
if ( pAmmoDef == NULL )
return;
C_BaseEntity *pEnt = ClientEntityList().GetEnt( m_iPlayer );
if ( pEnt )
{
C_BasePlayer *pPlayer = dynamic_cast<C_BasePlayer *>(pEnt);
if ( pPlayer && pPlayer->GetActiveWeapon() )
{
C_BaseCombatWeapon *pWpn = dynamic_cast<C_BaseCombatWeapon *>( pPlayer->GetActiveWeapon() );
if ( pWpn )
{
int iSeed = m_iSeed;
CShotManipulator Manipulator( m_vecDir );
for (int iShot = 0; iShot < m_iShots; iShot++)
{
RandomSeed( iSeed ); // init random system with this seed
// Don't run the biasing code for the player at the moment.
Vector vecDir = Manipulator.ApplySpread( Vector( m_flSpread, m_flSpread, m_flSpread ) );
Vector vecEnd = m_vecOrigin + vecDir * MAX_TRACE_LENGTH;
trace_t tr;
CTraceFilterSkipPlayerAndViewModelOnly traceFilter;
if( m_iShots > 1 && iShot % 2 )
{
// Half of the shotgun pellets are hulls that make it easier to hit targets with the shotgun.
UTIL_TraceHull( m_vecOrigin, vecEnd, Vector( -3, -3, -3 ), Vector( 3, 3, 3 ), MASK_SHOT, &traceFilter, &tr );
}
else
{
UTIL_TraceLine( m_vecOrigin, vecEnd, MASK_SHOT, &traceFilter, &tr);
}
if ( m_bDoTracers )
{
const char *pTracerName = pWpn->GetTracerType();
CEffectData data;
data.m_vStart = tr.startpos;
data.m_vOrigin = tr.endpos;
data.m_hEntity = pWpn->GetRefEHandle();
data.m_flScale = 0.0f;
data.m_fFlags |= TRACER_FLAG_USEATTACHMENT;
// Stomp the start, since it's not going to be used anyway
data.m_nAttachmentIndex = 1;
if ( pTracerName )
{
DispatchEffect( pTracerName, data );
}
else
{
DispatchEffect( "Tracer", data );
}
}
if ( m_bDoImpacts )
{
pWpn->DoImpactEffect( tr, pAmmoDef->DamageType( m_iAmmoID ) );
}
iSeed++;
}
}
}
}
}
void C_TEHL2MPFireBullets::PostDataUpdate( DataUpdateType_t updateType )
{
if ( m_bDoTracers || m_bDoImpacts )
{
CreateEffects();
}
}
IMPLEMENT_CLIENTCLASS_EVENT( C_TEHL2MPFireBullets, DT_TEHL2MPFireBullets, CTEHL2MPFireBullets );
BEGIN_RECV_TABLE_NOBASE(C_TEHL2MPFireBullets, DT_TEHL2MPFireBullets )
RecvPropVector( RECVINFO( m_vecOrigin ) ),
RecvPropVector( RECVINFO( m_vecDir ) ),
RecvPropInt( RECVINFO( m_iAmmoID ) ),
RecvPropInt( RECVINFO( m_iSeed ) ),
RecvPropInt( RECVINFO( m_iShots ) ),
RecvPropInt( RECVINFO( m_iPlayer ) ),
RecvPropInt( RECVINFO( m_iWeaponIndex ) ),
RecvPropFloat( RECVINFO( m_flSpread ) ),
RecvPropBool( RECVINFO( m_bDoImpacts ) ),
RecvPropBool( RECVINFO( m_bDoTracers ) ),
END_RECV_TABLE()

View File

@ -1,128 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Draws the normal TF2 or HL2 HUD.
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "clientmode_hl2mpnormal.h"
#include "vgui_int.h"
#include "hud.h"
#include <vgui/IInput.h>
#include <vgui/IPanel.h>
#include <vgui/ISurface.h>
#include <vgui_controls/AnimationController.h>
#include "iinput.h"
#include "hl2mpclientscoreboard.h"
#include "hl2mptextwindow.h"
#include "ienginevgui.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------
vgui::HScheme g_hVGuiCombineScheme = 0;
// Instance the singleton and expose the interface to it.
IClientMode *GetClientModeNormal()
{
static ClientModeHL2MPNormal g_ClientModeNormal;
return &g_ClientModeNormal;
}
ClientModeHL2MPNormal* GetClientModeHL2MPNormal()
{
Assert( dynamic_cast< ClientModeHL2MPNormal* >( GetClientModeNormal() ) );
return static_cast< ClientModeHL2MPNormal* >( GetClientModeNormal() );
}
//-----------------------------------------------------------------------------
// Purpose: this is the viewport that contains all the hud elements
//-----------------------------------------------------------------------------
class CHudViewport : public CBaseViewport
{
private:
DECLARE_CLASS_SIMPLE( CHudViewport, CBaseViewport );
protected:
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
gHUD.InitColors( pScheme );
SetPaintBackgroundEnabled( false );
}
virtual IViewPortPanel *CreatePanelByName( const char *szPanelName );
};
int ClientModeHL2MPNormal::GetDeathMessageStartHeight( void )
{
return m_pViewport->GetDeathMessageStartHeight();
}
IViewPortPanel* CHudViewport::CreatePanelByName( const char *szPanelName )
{
IViewPortPanel* newpanel = NULL;
if ( Q_strcmp( PANEL_SCOREBOARD, szPanelName) == 0 )
{
newpanel = new CHL2MPClientScoreBoardDialog( this );
return newpanel;
}
else if ( Q_strcmp(PANEL_INFO, szPanelName) == 0 )
{
newpanel = new CHL2MPTextWindow( this );
return newpanel;
}
else if ( Q_strcmp(PANEL_SPECGUI, szPanelName) == 0 )
{
newpanel = new CHL2MPSpectatorGUI( this );
return newpanel;
}
return BaseClass::CreatePanelByName( szPanelName );
}
//-----------------------------------------------------------------------------
// ClientModeHLNormal implementation
//-----------------------------------------------------------------------------
ClientModeHL2MPNormal::ClientModeHL2MPNormal()
{
m_pViewport = new CHudViewport();
m_pViewport->Start( gameuifuncs, gameeventmanager );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
ClientModeHL2MPNormal::~ClientModeHL2MPNormal()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ClientModeHL2MPNormal::Init()
{
BaseClass::Init();
// Load up the combine control panel scheme
g_hVGuiCombineScheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/CombinePanelScheme.res", "CombineScheme" );
if (!g_hVGuiCombineScheme)
{
Warning( "Couldn't load combine panel scheme!\n" );
}
}

View File

@ -1,47 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#if !defined( CLIENTMODE_HLNORMAL_H )
#define CLIENTMODE_HLNORMAL_H
#ifdef _WIN32
#pragma once
#endif
#include "clientmode_shared.h"
#include <vgui_controls/EditablePanel.h>
#include <vgui/Cursor.h>
class CHudViewport;
namespace vgui
{
typedef unsigned long HScheme;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class ClientModeHL2MPNormal : public ClientModeShared
{
public:
DECLARE_CLASS( ClientModeHL2MPNormal, ClientModeShared );
ClientModeHL2MPNormal();
~ClientModeHL2MPNormal();
virtual void Init();
virtual int GetDeathMessageStartHeight( void );
};
extern IClientMode *GetClientModeNormal();
extern vgui::HScheme g_hVGuiCombineScheme;
extern ClientModeHL2MPNormal* GetClientModeHL2MPNormal();
#endif // CLIENTMODE_HLNORMAL_H

View File

@ -1,116 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "hl2mp_hud_chat.h"
#include "hud_macros.h"
#include "text_message.h"
#include "vguicenterprint.h"
#include "vgui/ILocalize.h"
#include "c_team.h"
#include "c_playerresource.h"
#include "c_hl2mp_player.h"
#include "hl2mp_gamerules.h"
#include "ihudlcd.h"
DECLARE_HUDELEMENT( CHudChat );
DECLARE_HUD_MESSAGE( CHudChat, SayText );
DECLARE_HUD_MESSAGE( CHudChat, SayText2 );
DECLARE_HUD_MESSAGE( CHudChat, TextMsg );
//=====================
//CHudChatLine
//=====================
void CHudChatLine::ApplySchemeSettings(vgui::IScheme *pScheme)
{
BaseClass::ApplySchemeSettings( pScheme );
}
//=====================
//CHudChatInputLine
//=====================
void CHudChatInputLine::ApplySchemeSettings(vgui::IScheme *pScheme)
{
BaseClass::ApplySchemeSettings(pScheme);
}
//=====================
//CHudChat
//=====================
CHudChat::CHudChat( const char *pElementName ) : BaseClass( pElementName )
{
}
void CHudChat::CreateChatInputLine( void )
{
m_pChatInput = new CHudChatInputLine( this, "ChatInputLine" );
m_pChatInput->SetVisible( false );
}
void CHudChat::CreateChatLines( void )
{
m_ChatLine = new CHudChatLine( this, "ChatLine1" );
m_ChatLine->SetVisible( false );
}
void CHudChat::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
}
void CHudChat::Init( void )
{
BaseClass::Init();
HOOK_HUD_MESSAGE( CHudChat, SayText );
HOOK_HUD_MESSAGE( CHudChat, SayText2 );
HOOK_HUD_MESSAGE( CHudChat, TextMsg );
}
//-----------------------------------------------------------------------------
// Purpose: Overrides base reset to not cancel chat at round restart
//-----------------------------------------------------------------------------
void CHudChat::Reset( void )
{
}
int CHudChat::GetChatInputOffset( void )
{
if ( m_pChatInput->IsVisible() )
{
return m_iFontHeight;
}
else
return 0;
}
Color CHudChat::GetClientColor( int clientIndex )
{
if ( clientIndex == 0 ) // console msg
{
return g_ColorYellow;
}
else if( g_PR )
{
switch ( g_PR->GetTeam( clientIndex ) )
{
case TEAM_COMBINE : return g_ColorBlue;
case TEAM_REBELS : return g_ColorRed;
default : return g_ColorYellow;
}
}
return g_ColorYellow;
}

View File

@ -1,65 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef CS_HUD_CHAT_H
#define CS_HUD_CHAT_H
#ifdef _WIN32
#pragma once
#endif
#include <hud_basechat.h>
class CHudChatLine : public CBaseHudChatLine
{
DECLARE_CLASS_SIMPLE( CHudChatLine, CBaseHudChatLine );
public:
CHudChatLine( vgui::Panel *parent, const char *panelName ) : CBaseHudChatLine( parent, panelName ) {}
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
void MsgFunc_SayText(bf_read &msg);
private:
CHudChatLine( const CHudChatLine & ); // not defined, not accessible
};
//-----------------------------------------------------------------------------
// Purpose: The prompt and text entry area for chat messages
//-----------------------------------------------------------------------------
class CHudChatInputLine : public CBaseHudChatInputLine
{
DECLARE_CLASS_SIMPLE( CHudChatInputLine, CBaseHudChatInputLine );
public:
CHudChatInputLine( CBaseHudChat *parent, char const *panelName ) : CBaseHudChatInputLine( parent, panelName ) {}
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
};
class CHudChat : public CBaseHudChat
{
DECLARE_CLASS_SIMPLE( CHudChat, CBaseHudChat );
public:
CHudChat( const char *pElementName );
virtual void CreateChatInputLine( void );
virtual void CreateChatLines( void );
virtual void Init( void );
virtual void Reset( void );
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
int GetChatInputOffset( void );
virtual Color GetClientColor( int clientIndex );
};
#endif //CS_HUD_CHAT_H

View File

@ -1,222 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: HUD Target ID element
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "c_hl2mp_player.h"
#include "c_playerresource.h"
#include "vgui_entitypanel.h"
#include "iclientmode.h"
#include "vgui/ILocalize.h"
#include "hl2mp_gamerules.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define PLAYER_HINT_DISTANCE 150
#define PLAYER_HINT_DISTANCE_SQ (PLAYER_HINT_DISTANCE*PLAYER_HINT_DISTANCE)
static ConVar hud_centerid( "hud_centerid", "1" );
static ConVar hud_showtargetid( "hud_showtargetid", "1" );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CTargetID : public CHudElement, public vgui::Panel
{
DECLARE_CLASS_SIMPLE( CTargetID, vgui::Panel );
public:
CTargetID( const char *pElementName );
void Init( void );
virtual void ApplySchemeSettings( vgui::IScheme *scheme );
virtual void Paint( void );
void VidInit( void );
private:
Color GetColorForTargetTeam( int iTeamNumber );
vgui::HFont m_hFont;
int m_iLastEntIndex;
float m_flLastChangeTime;
};
DECLARE_HUDELEMENT( CTargetID );
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTargetID::CTargetID( const char *pElementName ) :
CHudElement( pElementName ), BaseClass( NULL, "TargetID" )
{
vgui::Panel *pParent = g_pClientMode->GetViewport();
SetParent( pParent );
m_hFont = g_hFontTrebuchet24;
m_flLastChangeTime = 0;
m_iLastEntIndex = 0;
SetHiddenBits( HIDEHUD_MISCSTATUS );
}
//-----------------------------------------------------------------------------
// Purpose: Setup
//-----------------------------------------------------------------------------
void CTargetID::Init( void )
{
};
void CTargetID::ApplySchemeSettings( vgui::IScheme *scheme )
{
BaseClass::ApplySchemeSettings( scheme );
m_hFont = scheme->GetFont( "TargetID", IsProportional() );
SetPaintBackgroundEnabled( false );
}
//-----------------------------------------------------------------------------
// Purpose: clear out string etc between levels
//-----------------------------------------------------------------------------
void CTargetID::VidInit()
{
CHudElement::VidInit();
m_flLastChangeTime = 0;
m_iLastEntIndex = 0;
}
Color CTargetID::GetColorForTargetTeam( int iTeamNumber )
{
return GameResources()->GetTeamColor( iTeamNumber );
}
//-----------------------------------------------------------------------------
// Purpose: Draw function for the element
//-----------------------------------------------------------------------------
void CTargetID::Paint()
{
#define MAX_ID_STRING 256
wchar_t sIDString[ MAX_ID_STRING ];
sIDString[0] = 0;
C_HL2MP_Player *pPlayer = C_HL2MP_Player::GetLocalHL2MPPlayer();
if ( !pPlayer )
return;
Color c;
// Get our target's ent index
int iEntIndex = pPlayer->GetIDTarget();
// Didn't find one?
if ( !iEntIndex )
{
// Check to see if we should clear our ID
if ( m_flLastChangeTime && (gpGlobals->curtime > (m_flLastChangeTime + 0.5)) )
{
m_flLastChangeTime = 0;
sIDString[0] = 0;
m_iLastEntIndex = 0;
}
else
{
// Keep re-using the old one
iEntIndex = m_iLastEntIndex;
}
}
else
{
m_flLastChangeTime = gpGlobals->curtime;
}
// Is this an entindex sent by the server?
if ( iEntIndex )
{
C_BasePlayer *pPlayer = static_cast<C_BasePlayer*>(cl_entitylist->GetEnt( iEntIndex ));
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
const char *printFormatString = NULL;
wchar_t wszPlayerName[ MAX_PLAYER_NAME_LENGTH ];
wchar_t wszHealthText[ 10 ];
bool bShowHealth = false;
bool bShowPlayerName = false;
// Some entities we always want to check, cause the text may change
// even while we're looking at it
// Is it a player?
if ( IsPlayerIndex( iEntIndex ) )
{
c = GetColorForTargetTeam( pPlayer->GetTeamNumber() );
bShowPlayerName = true;
g_pVGuiLocalize->ConvertANSIToUnicode( pPlayer->GetPlayerName(), wszPlayerName, sizeof(wszPlayerName) );
if ( HL2MPRules()->IsTeamplay() == true && pPlayer->InSameTeam(pLocalPlayer) )
{
printFormatString = "#Playerid_sameteam";
bShowHealth = true;
}
else
{
printFormatString = "#Playerid_diffteam";
}
if ( bShowHealth )
{
_snwprintf( wszHealthText, ARRAYSIZE(wszHealthText) - 1, L"%.0f%%", ((float)pPlayer->GetHealth() / (float)pPlayer->GetMaxHealth() ) );
wszHealthText[ ARRAYSIZE(wszHealthText)-1 ] = '\0';
}
}
if ( printFormatString )
{
if ( bShowPlayerName && bShowHealth )
{
g_pVGuiLocalize->ConstructString( sIDString, sizeof(sIDString), g_pVGuiLocalize->Find(printFormatString), 2, wszPlayerName, wszHealthText );
}
else if ( bShowPlayerName )
{
g_pVGuiLocalize->ConstructString( sIDString, sizeof(sIDString), g_pVGuiLocalize->Find(printFormatString), 1, wszPlayerName );
}
else if ( bShowHealth )
{
g_pVGuiLocalize->ConstructString( sIDString, sizeof(sIDString), g_pVGuiLocalize->Find(printFormatString), 1, wszHealthText );
}
else
{
g_pVGuiLocalize->ConstructString( sIDString, sizeof(sIDString), g_pVGuiLocalize->Find(printFormatString), 0 );
}
}
if ( sIDString[0] )
{
int wide, tall;
int ypos = YRES(260);
int xpos = XRES(10);
vgui::surface()->GetTextSize( m_hFont, sIDString, wide, tall );
if( hud_centerid.GetInt() == 0 )
{
ypos = YRES(420);
}
else
{
xpos = (ScreenWidth() - wide) / 2;
}
vgui::surface()->DrawSetTextFont( m_hFont );
vgui::surface()->DrawSetTextPos( xpos, ypos );
vgui::surface()->DrawSetTextColor( c );
vgui::surface()->DrawPrintText( sIDString, wcslen(sIDString) );
}
}
}

View File

@ -1,189 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: HUD Target ID element
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "c_hl2mp_player.h"
#include "c_playerresource.h"
#include "vgui_entitypanel.h"
#include "iclientmode.h"
#include "vgui/ILocalize.h"
#include "hl2mp_gamerules.h"
#include "c_team.h"
#include <vgui_controls/AnimationController.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Purpose: Displays current ammunition level
//-----------------------------------------------------------------------------
class CTeamPlayHud : public vgui::Panel, public CHudElement
{
DECLARE_CLASS_SIMPLE( CTeamPlayHud, vgui::Panel );
public:
CTeamPlayHud( const char *pElementName );
void Reset();
virtual void PerformLayout();
protected:
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
virtual void OnThink();
private:
vgui::HFont m_hFont;
Color m_bgColor;
vgui::Label *m_pWarmupLabel; // "Warmup Mode"
vgui::Label *m_pBackground; // black box
bool m_bSuitAuxPowerUsed;
CPanelAnimationVarAliasType( int, m_iTextX, "text_xpos", "8", "proportional_int" );
CPanelAnimationVarAliasType( int, m_iTextY, "text_ypos", "8", "proportional_int" );
};
DECLARE_HUDELEMENT( CTeamPlayHud );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CTeamPlayHud::CTeamPlayHud( const char *pElementName ) : BaseClass(NULL, "TeamDisplay"), CHudElement( pElementName )
{
vgui::Panel *pParent = g_pClientMode->GetViewport();
SetParent( pParent );
SetVisible( false );
SetAlpha( 255 );
m_pBackground = new vgui::Label( this, "Background", "" );
m_pWarmupLabel = new vgui::Label( this, "RoundState_warmup", "test label" /*g_pVGuiLocalize->Find( "#Clan_warmup_mode" )*/ );
m_pWarmupLabel->SetPaintBackgroundEnabled( false );
m_pWarmupLabel->SetPaintBorderEnabled( false );
m_pWarmupLabel->SizeToContents();
m_pWarmupLabel->SetContentAlignment( vgui::Label::a_west );
m_pWarmupLabel->SetFgColor( GetFgColor() );
m_bSuitAuxPowerUsed = false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTeamPlayHud::Reset()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTeamPlayHud::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
SetFgColor( Color(0,0,0,0) ); //GetSchemeColor("RoundStateFg", pScheme) );
m_hFont = pScheme->GetFont( "Default", true );
m_pBackground->SetBgColor( GetSchemeColor("BgColor", pScheme) );
m_pBackground->SetPaintBackgroundType( 2 );
SetAlpha( 255 );
SetBgColor( Color( 0, 0, 0, 0 ) );
SetPaintBackgroundType( 0 );
}
//-----------------------------------------------------------------------------
// Purpose: Resizes the label
//-----------------------------------------------------------------------------
void CTeamPlayHud::PerformLayout()
{
BaseClass::PerformLayout();
int wide, tall;
GetSize( wide, tall );
// find the widest line
int labelWide = m_pWarmupLabel->GetWide();
// find the total height
int fontTall = vgui::surface()->GetFontTall( m_hFont );
int labelTall = fontTall;
labelWide += m_iTextX*2;
labelTall += m_iTextY*2;
m_pBackground->SetBounds( 0, 0, labelWide, labelTall );
int xOffset = (labelWide - m_pWarmupLabel->GetWide())/2;
m_pWarmupLabel->SetPos( 0 + xOffset, 0 + m_iTextY );
}
//-----------------------------------------------------------------------------
// Purpose: Updates the label color each frame
//-----------------------------------------------------------------------------
void CTeamPlayHud::OnThink()
{
SetVisible( false );
C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
if ( pLocalPlayer == NULL )
return;
if ( HL2MPRules()->IsTeamplay() == false )
return;
if ( pLocalPlayer->IsAlive() == false )
return;
if ( pLocalPlayer->m_HL2Local.m_flSuitPower < 100 )
{
if ( m_bSuitAuxPowerUsed == false )
{
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("FadeOutTeamLine");
m_bSuitAuxPowerUsed = true;
}
}
else
{
if ( m_bSuitAuxPowerUsed == true )
{
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("FadeInTeamLine");
m_bSuitAuxPowerUsed = false;
}
}
int iTeamNumber = pLocalPlayer->GetTeamNumber();
Color c = GameResources()->GetTeamColor( iTeamNumber );
wchar_t string1[1024];
C_Team *pTeam = GetGlobalTeam( iTeamNumber );
if ( pTeam )
{
wchar_t TeamName[64];
g_pVGuiLocalize->ConvertANSIToUnicode( pTeam->Get_Name(), TeamName, sizeof(TeamName) );
g_pVGuiLocalize->ConstructString( string1, sizeof(string1), g_pVGuiLocalize->Find("#Team"), 1, TeamName );
m_pBackground->SetFgColor( GetFgColor() );
m_pWarmupLabel->SetFgColor(c);
m_pWarmupLabel->SetText( string1 );
m_pWarmupLabel->SetVisible( true );
m_pWarmupLabel->SizeToContents();
SetVisible( true );
}
InvalidateLayout();
}

View File

@ -1,352 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Draws CSPort's death notices
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hudelement.h"
#include "hud_macros.h"
#include "c_playerresource.h"
#include "clientmode_hl2mpnormal.h"
#include <vgui_controls/Controls.h>
#include <vgui_controls/Panel.h>
#include <vgui/ISurface.h>
#include <vgui/ILocalize.h>
#include <KeyValues.h>
#include "c_baseplayer.h"
#include "c_team.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static ConVar hud_deathnotice_time( "hud_deathnotice_time", "6", 0 );
// Player entries in a death notice
struct DeathNoticePlayer
{
char szName[MAX_PLAYER_NAME_LENGTH];
int iEntIndex;
};
// Contents of each entry in our list of death notices
struct DeathNoticeItem
{
DeathNoticePlayer Killer;
DeathNoticePlayer Victim;
CHudTexture *iconDeath;
int iSuicide;
float flDisplayTime;
bool bHeadshot;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CHudDeathNotice : public CHudElement, public vgui::Panel
{
DECLARE_CLASS_SIMPLE( CHudDeathNotice, vgui::Panel );
public:
CHudDeathNotice( const char *pElementName );
void Init( void );
void VidInit( void );
virtual bool ShouldDraw( void );
virtual void Paint( void );
virtual void ApplySchemeSettings( vgui::IScheme *scheme );
void SetColorForNoticePlayer( int iTeamNumber );
void RetireExpiredDeathNotices( void );
virtual void FireGameEvent( IGameEvent * event );
private:
CPanelAnimationVarAliasType( float, m_flLineHeight, "LineHeight", "15", "proportional_float" );
CPanelAnimationVar( float, m_flMaxDeathNotices, "MaxDeathNotices", "4" );
CPanelAnimationVar( bool, m_bRightJustify, "RightJustify", "1" );
CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "HudNumbersTimer" );
// Texture for skull symbol
CHudTexture *m_iconD_skull;
CHudTexture *m_iconD_headshot;
CUtlVector<DeathNoticeItem> m_DeathNotices;
};
using namespace vgui;
DECLARE_HUDELEMENT( CHudDeathNotice );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CHudDeathNotice::CHudDeathNotice( const char *pElementName ) :
CHudElement( pElementName ), BaseClass( NULL, "HudDeathNotice" )
{
vgui::Panel *pParent = g_pClientMode->GetViewport();
SetParent( pParent );
m_iconD_headshot = NULL;
m_iconD_skull = NULL;
SetHiddenBits( HIDEHUD_MISCSTATUS );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHudDeathNotice::ApplySchemeSettings( IScheme *scheme )
{
BaseClass::ApplySchemeSettings( scheme );
SetPaintBackgroundEnabled( false );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHudDeathNotice::Init( void )
{
ListenForGameEvent( "player_death" );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHudDeathNotice::VidInit( void )
{
m_iconD_skull = gHUD.GetIcon( "d_skull" );
m_DeathNotices.Purge();
}
//-----------------------------------------------------------------------------
// Purpose: Draw if we've got at least one death notice in the queue
//-----------------------------------------------------------------------------
bool CHudDeathNotice::ShouldDraw( void )
{
return ( CHudElement::ShouldDraw() && ( m_DeathNotices.Count() ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHudDeathNotice::SetColorForNoticePlayer( int iTeamNumber )
{
surface()->DrawSetTextColor( GameResources()->GetTeamColor( iTeamNumber ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHudDeathNotice::Paint()
{
if ( !m_iconD_skull )
return;
int yStart = GetClientModeHL2MPNormal()->GetDeathMessageStartHeight();
surface()->DrawSetTextFont( m_hTextFont );
surface()->DrawSetTextColor( GameResources()->GetTeamColor( 0 ) );
int iCount = m_DeathNotices.Count();
for ( int i = 0; i < iCount; i++ )
{
CHudTexture *icon = m_DeathNotices[i].iconDeath;
if ( !icon )
continue;
wchar_t victim[ 256 ];
wchar_t killer[ 256 ];
// Get the team numbers for the players involved
int iKillerTeam = 0;
int iVictimTeam = 0;
if( g_PR )
{
iKillerTeam = g_PR->GetTeam( m_DeathNotices[i].Killer.iEntIndex );
iVictimTeam = g_PR->GetTeam( m_DeathNotices[i].Victim.iEntIndex );
}
g_pVGuiLocalize->ConvertANSIToUnicode( m_DeathNotices[i].Victim.szName, victim, sizeof( victim ) );
g_pVGuiLocalize->ConvertANSIToUnicode( m_DeathNotices[i].Killer.szName, killer, sizeof( killer ) );
// Get the local position for this notice
int len = UTIL_ComputeStringWidth( m_hTextFont, victim );
int y = yStart + (m_flLineHeight * i);
int iconWide;
int iconTall;
if( icon->bRenderUsingFont )
{
iconWide = surface()->GetCharacterWidth( icon->hFont, icon->cCharacterInFont );
iconTall = surface()->GetFontTall( icon->hFont );
}
else
{
float scale = ( (float)ScreenHeight() / 480.0f ); //scale based on 640x480
iconWide = (int)( scale * (float)icon->Width() );
iconTall = (int)( scale * (float)icon->Height() );
}
int x;
if ( m_bRightJustify )
{
x = GetWide() - len - iconWide;
}
else
{
x = 0;
}
// Only draw killers name if it wasn't a suicide
if ( !m_DeathNotices[i].iSuicide )
{
if ( m_bRightJustify )
{
x -= UTIL_ComputeStringWidth( m_hTextFont, killer );
}
SetColorForNoticePlayer( iKillerTeam );
// Draw killer's name
surface()->DrawSetTextPos( x, y );
surface()->DrawSetTextFont( m_hTextFont );
surface()->DrawUnicodeString( killer );
surface()->DrawGetTextPos( x, y );
}
Color iconColor( 255, 80, 0, 255 );
// Draw death weapon
//If we're using a font char, this will ignore iconTall and iconWide
icon->DrawSelf( x, y, iconWide, iconTall, iconColor );
x += iconWide;
SetColorForNoticePlayer( iVictimTeam );
// Draw victims name
surface()->DrawSetTextPos( x, y );
surface()->DrawSetTextFont( m_hTextFont ); //reset the font, draw icon can change it
surface()->DrawUnicodeString( victim );
}
// Now retire any death notices that have expired
RetireExpiredDeathNotices();
}
//-----------------------------------------------------------------------------
// Purpose: This message handler may be better off elsewhere
//-----------------------------------------------------------------------------
void CHudDeathNotice::RetireExpiredDeathNotices( void )
{
// Loop backwards because we might remove one
int iSize = m_DeathNotices.Size();
for ( int i = iSize-1; i >= 0; i-- )
{
if ( m_DeathNotices[i].flDisplayTime < gpGlobals->curtime )
{
m_DeathNotices.Remove(i);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Server's told us that someone's died
//-----------------------------------------------------------------------------
void CHudDeathNotice::FireGameEvent( IGameEvent * event )
{
if (!g_PR)
return;
if ( hud_deathnotice_time.GetFloat() == 0 )
return;
// the event should be "player_death"
int killer = engine->GetPlayerForUserID( event->GetInt("attacker") );
int victim = engine->GetPlayerForUserID( event->GetInt("userid") );
const char *killedwith = event->GetString( "weapon" );
char fullkilledwith[128];
if ( killedwith && *killedwith )
{
Q_snprintf( fullkilledwith, sizeof(fullkilledwith), "death_%s", killedwith );
}
else
{
fullkilledwith[0] = 0;
}
// Do we have too many death messages in the queue?
if ( m_DeathNotices.Count() > 0 &&
m_DeathNotices.Count() >= (int)m_flMaxDeathNotices )
{
// Remove the oldest one in the queue, which will always be the first
m_DeathNotices.Remove(0);
}
// Get the names of the players
const char *killer_name = g_PR->GetPlayerName( killer );
const char *victim_name = g_PR->GetPlayerName( victim );
if ( !killer_name )
killer_name = "";
if ( !victim_name )
victim_name = "";
// Make a new death notice
DeathNoticeItem deathMsg;
deathMsg.Killer.iEntIndex = killer;
deathMsg.Victim.iEntIndex = victim;
Q_strncpy( deathMsg.Killer.szName, killer_name, MAX_PLAYER_NAME_LENGTH );
Q_strncpy( deathMsg.Victim.szName, victim_name, MAX_PLAYER_NAME_LENGTH );
deathMsg.flDisplayTime = gpGlobals->curtime + hud_deathnotice_time.GetFloat();
deathMsg.iSuicide = ( !killer || killer == victim );
// Try and find the death identifier in the icon list
deathMsg.iconDeath = gHUD.GetIcon( fullkilledwith );
if ( !deathMsg.iconDeath || deathMsg.iSuicide )
{
// Can't find it, so use the default skull & crossbones icon
deathMsg.iconDeath = m_iconD_skull;
}
// Add it to our list of death notices
m_DeathNotices.AddToTail( deathMsg );
char sDeathMsg[512];
// Record the death notice in the console
if ( deathMsg.iSuicide )
{
if ( !strcmp( fullkilledwith, "d_worldspawn" ) )
{
Q_snprintf( sDeathMsg, sizeof( sDeathMsg ), "%s died.\n", deathMsg.Victim.szName );
}
else //d_world
{
Q_snprintf( sDeathMsg, sizeof( sDeathMsg ), "%s suicided.\n", deathMsg.Victim.szName );
}
}
else
{
Q_snprintf( sDeathMsg, sizeof( sDeathMsg ), "%s killed %s", deathMsg.Killer.szName, deathMsg.Victim.szName );
if ( fullkilledwith && *fullkilledwith && (*fullkilledwith > 13 ) )
{
Q_strncat( sDeathMsg, VarArgs( " with %s.\n", fullkilledwith+6 ), sizeof( sDeathMsg ), COPY_ALL_CHARACTERS );
}
}
Msg( "%s", sDeathMsg );
}

View File

@ -1,431 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "backgroundpanel.h"
#include <vgui/IVGui.h>
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui_controls/Label.h>
#include <vgui/ILocalize.h>
#include "vgui_controls/BuildGroup.h"
#include "vgui_controls/BitmapImagePanel.h"
using namespace vgui;
#define DEBUG_WINDOW_RESIZING 0
#define DEBUG_WINDOW_REPOSITIONING 0
class CaptionLabel : public Label
{
public:
CaptionLabel(Panel *parent, const char *panelName, const char *text) : Label(parent, panelName, text)
{
}
virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
{
Label::ApplySchemeSettings( pScheme );
SetFont( pScheme->GetFont( "MenuTitle", IsProportional() ) );
}
};
//-----------------------------------------------------------------------------
// Purpose: transform a normalized value into one that is scaled based the minimum
// of the horizontal and vertical ratios
//-----------------------------------------------------------------------------
static int GetAlternateProportionalValueFromNormal(int normalizedValue)
{
int wide, tall;
GetHudSize( wide, tall );
int proH, proW;
surface()->GetProportionalBase( proW, proH );
double scaleH = (double)tall / (double)proH;
double scaleW = (double)wide / (double)proW;
double scale = (scaleW < scaleH) ? scaleW : scaleH;
return (int)( normalizedValue * scale );
}
//-----------------------------------------------------------------------------
// Purpose: transform a standard scaled value into one that is scaled based the minimum
// of the horizontal and vertical ratios
//-----------------------------------------------------------------------------
int GetAlternateProportionalValueFromScaled( HScheme hScheme, int scaledValue)
{
return GetAlternateProportionalValueFromNormal( scheme()->GetProportionalNormalizedValueEx( hScheme, scaledValue ) );
}
//-----------------------------------------------------------------------------
// Purpose: moves and resizes a single control
//-----------------------------------------------------------------------------
static void RepositionControl( Panel *pPanel )
{
int x, y, w, h;
pPanel->GetBounds(x, y, w, h);
#if DEBUG_WINDOW_RESIZING
int x1, y1, w1, h1;
pPanel->GetBounds(x1, y1, w1, h1);
int x2, y2, w2, h2;
x2 = scheme()->GetProportionalNormalizedValueEx( pPanel->GetScheme(), x1 );
y2 = scheme()->GetProportionalNormalizedValueEx( pPanel->GetScheme(), y1 );
w2 = scheme()->GetProportionalNormalizedValueEx( pPanel->GetScheme(), w1 );
h2 = scheme()->GetProportionalNormalizedValueEx( pPanel->GetScheme(), h1 );
#endif
x = GetAlternateProportionalValueFromScaled(pPanel->GetScheme(),x);
y = GetAlternateProportionalValueFromScaled(pPanel->GetScheme(),y);
w = GetAlternateProportionalValueFromScaled(pPanel->GetScheme(),w);
h = GetAlternateProportionalValueFromScaled(pPanel->GetScheme(),h);
pPanel->SetBounds(x, y, w, h);
#if DEBUG_WINDOW_RESIZING
DevMsg( "Resizing '%s' from (%d,%d) %dx%d to (%d,%d) %dx%d -- initially was (%d,%d) %dx%d\n",
pPanel->GetName(), x1, y1, w1, h1, x, y, w, h, x2, y2, w2, h2 );
#endif
}
//-----------------------------------------------------------------------------
// Purpose: Sets colors etc for background image panels
//-----------------------------------------------------------------------------
void ApplyBackgroundSchemeSettings( EditablePanel *pWindow, vgui::IScheme *pScheme )
{
Color bgColor = Color( 255, 255, 255, pScheme->GetColor( "BgColor", Color( 0, 0, 0, 0 ) )[3] );
Color fgColor = pScheme->GetColor( "FgColor", Color( 0, 0, 0, 0 ) );
if ( !pWindow )
return;
CBitmapImagePanel *pBitmapPanel;
// corners --------------------------------------------
pBitmapPanel = dynamic_cast< CBitmapImagePanel * >(pWindow->FindChildByName( "TopLeftPanel" ));
if ( pBitmapPanel )
{
pBitmapPanel->setImageColor( bgColor );
}
pBitmapPanel = dynamic_cast< CBitmapImagePanel * >(pWindow->FindChildByName( "TopRightPanel" ));
if ( pBitmapPanel )
{
pBitmapPanel->setImageColor( bgColor );
}
pBitmapPanel = dynamic_cast< CBitmapImagePanel * >(pWindow->FindChildByName( "BottomLeftPanel" ));
if ( pBitmapPanel )
{
pBitmapPanel->setImageColor( bgColor );
}
pBitmapPanel = dynamic_cast< CBitmapImagePanel * >(pWindow->FindChildByName( "BottomRightPanel" ));
if ( pBitmapPanel )
{
pBitmapPanel->setImageColor( bgColor );
}
// background -----------------------------------------
pBitmapPanel = dynamic_cast< CBitmapImagePanel * >(pWindow->FindChildByName( "TopSolid" ));
if ( pBitmapPanel )
{
pBitmapPanel->setImageColor( bgColor );
}
pBitmapPanel = dynamic_cast< CBitmapImagePanel * >(pWindow->FindChildByName( "UpperMiddleSolid" ));
if ( pBitmapPanel )
{
pBitmapPanel->setImageColor( bgColor );
}
pBitmapPanel = dynamic_cast< CBitmapImagePanel * >(pWindow->FindChildByName( "LowerMiddleSolid" ));
if ( pBitmapPanel )
{
pBitmapPanel->setImageColor( bgColor );
}
pBitmapPanel = dynamic_cast< CBitmapImagePanel * >(pWindow->FindChildByName( "BottomSolid" ));
if ( pBitmapPanel )
{
pBitmapPanel->setImageColor( bgColor );
}
// Logo -----------------------------------------------
pBitmapPanel = dynamic_cast< CBitmapImagePanel * >(pWindow->FindChildByName( "ExclamationPanel" ));
if ( pBitmapPanel )
{
pBitmapPanel->setImageColor( fgColor );
}
}
//-----------------------------------------------------------------------------
// Purpose: Re-aligns background image panels so they are touching.
//-----------------------------------------------------------------------------
static void FixupBackgroundPanels( EditablePanel *pWindow, int offsetX, int offsetY )
{
if ( !pWindow )
return;
int screenWide, screenTall;
pWindow->GetSize( screenWide, screenTall );
int inset = GetAlternateProportionalValueFromNormal( 20 );
int cornerSize = GetAlternateProportionalValueFromNormal( 10 );
int titleHeight = GetAlternateProportionalValueFromNormal( 42 );
int mainHeight = GetAlternateProportionalValueFromNormal( 376 );
int logoSize = titleHeight;
int captionInset = GetAlternateProportionalValueFromNormal( 76 );
Panel *pPanel;
// corners --------------------------------------------
pPanel = pWindow->FindChildByName( "TopLeftPanel" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( offsetX + inset, offsetY + inset, cornerSize, cornerSize );
}
pPanel = pWindow->FindChildByName( "TopRightPanel" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( screenWide - offsetX - inset - cornerSize, offsetY + inset, cornerSize, cornerSize );
}
pPanel = pWindow->FindChildByName( "BottomLeftPanel" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( offsetX + inset, screenTall - offsetY - inset - cornerSize, cornerSize, cornerSize );
}
pPanel = pWindow->FindChildByName( "BottomRightPanel" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( screenWide - offsetX - inset - cornerSize, screenTall - offsetY - inset - cornerSize, cornerSize, cornerSize );
}
// background -----------------------------------------
pPanel = pWindow->FindChildByName( "TopSolid" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( offsetX + inset + cornerSize, offsetY + inset, screenWide - 2*offsetX - 2*inset - 2*cornerSize, cornerSize );
}
pPanel = pWindow->FindChildByName( "UpperMiddleSolid" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( offsetX + inset, offsetY + inset + cornerSize, screenWide - 2*offsetX - 2*inset, titleHeight );
}
pPanel = pWindow->FindChildByName( "LowerMiddleSolid" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( offsetX + inset + cornerSize, screenTall - offsetY - inset - cornerSize, screenWide - 2*offsetX - 2*inset - 2*cornerSize, cornerSize );
}
pPanel = pWindow->FindChildByName( "BottomSolid" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( offsetX + inset, screenTall - offsetY - inset - cornerSize - mainHeight, screenWide - 2*offsetX - 2*inset, mainHeight );
}
// transparent border ---------------------------------
pPanel = pWindow->FindChildByName( "TopClear" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( 0, 0, screenWide, offsetY + inset );
}
pPanel = pWindow->FindChildByName( "BottomClear" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( 0, screenTall - offsetY - inset, screenWide, offsetY + inset );
}
pPanel = pWindow->FindChildByName( "LeftClear" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( 0, offsetY + inset, offsetX + inset, screenTall - 2*offsetY - 2*inset );
}
pPanel = pWindow->FindChildByName( "RightClear" );
if ( pPanel )
{
pPanel->SetZPos( -20 );
pPanel->SetBounds( screenWide - offsetX - inset, offsetY + inset, offsetX + inset, screenTall - 2*offsetY - 2*inset );
}
// Logo -----------------------------------------------
int logoInset = (cornerSize + titleHeight - logoSize)/2;
pPanel = pWindow->FindChildByName( "ExclamationPanel" );
if ( pPanel )
{
pPanel->SetZPos( -19 ); // higher than the background
pPanel->SetBounds( offsetX + inset + logoInset, offsetY + inset + logoInset, logoSize, logoSize );
}
// Title caption --------------------------------------
pPanel = dynamic_cast< Label * >(pWindow->FindChildByName( "CaptionLabel" ));
if ( pPanel )
{
pPanel->SetZPos( -19 ); // higher than the background
pPanel->SetBounds( offsetX + captionInset/*inset + 2*logoInset + logoSize*/, offsetY + inset + logoInset, screenWide, logoSize );
}
}
//-----------------------------------------------------------------------------
// Purpose: Creates background image panels
//-----------------------------------------------------------------------------
void CreateBackground( EditablePanel *pWindow )
{
// corners --------------------------------------------
new CBitmapImagePanel( pWindow, "TopLeftPanel", "gfx/vgui/round_corner_nw" );
new CBitmapImagePanel( pWindow, "TopRightPanel", "gfx/vgui/round_corner_ne" );
new CBitmapImagePanel( pWindow, "BottomLeftPanel", "gfx/vgui/round_corner_sw" );
new CBitmapImagePanel( pWindow, "BottomRightPanel", "gfx/vgui/round_corner_se" );
// background -----------------------------------------
new CBitmapImagePanel( pWindow, "TopSolid", "gfx/vgui/solid_background" );
new CBitmapImagePanel( pWindow, "UpperMiddleSolid", "gfx/vgui/solid_background" );
new CBitmapImagePanel( pWindow, "LowerMiddleSolid", "gfx/vgui/solid_background" );
new CBitmapImagePanel( pWindow, "BottomSolid", "gfx/vgui/solid_background" );
// transparent border ---------------------------------
new CBitmapImagePanel( pWindow, "TopClear", "gfx/vgui/trans_background" );
new CBitmapImagePanel( pWindow, "BottomClear", "gfx/vgui/trans_background" );
new CBitmapImagePanel( pWindow, "LeftClear", "gfx/vgui/trans_background" );
new CBitmapImagePanel( pWindow, "RightClear", "gfx/vgui/trans_background" );
// Logo -----------------------------------------------
new CBitmapImagePanel( pWindow, "ExclamationPanel", "gfx/vgui/hl2mp_logo" );
// Title caption --------------------------------------
Panel *pPanel = dynamic_cast< Label * >(pWindow->FindChildByName( "CaptionLabel" ));
if ( !pPanel )
new CaptionLabel( pWindow, "CaptionLabel", "" );
}
void ResizeWindowControls( EditablePanel *pWindow, int tall, int wide, int offsetX, int offsetY )
{
if (!pWindow || !pWindow->GetBuildGroup() || !pWindow->GetBuildGroup()->GetPanelList())
return;
CUtlVector<PHandle> *panelList = pWindow->GetBuildGroup()->GetPanelList();
CUtlVector<Panel *> resizedPanels;
CUtlVector<Panel *> movedPanels;
// Resize to account for 1.25 aspect ratio (1280x1024) screens
{
for ( int i = 0; i < panelList->Size(); ++i )
{
PHandle handle = (*panelList)[i];
Panel *panel = handle.Get();
bool found = false;
for ( int j = 0; j < resizedPanels.Size(); ++j )
{
if (panel == resizedPanels[j])
found = true;
}
if (!panel || found)
{
continue;
}
resizedPanels.AddToTail( panel ); // don't move a panel more than once
if ( panel != pWindow )
{
RepositionControl( panel );
}
}
}
// and now re-center them. Woohoo!
for ( int i = 0; i < panelList->Size(); ++i )
{
PHandle handle = (*panelList)[i];
Panel *panel = handle.Get();
bool found = false;
for ( int j = 0; j < movedPanels.Size(); ++j )
{
if (panel == movedPanels[j])
found = true;
}
if (!panel || found)
{
continue;
}
movedPanels.AddToTail( panel ); // don't move a panel more than once
if ( panel != pWindow )
{
int x, y;
panel->GetPos( x, y );
panel->SetPos( x + offsetX, y + offsetY );
#if DEBUG_WINDOW_REPOSITIONING
DevMsg( "Repositioning '%s' from (%d,%d) to (%d,%d) -- a distance of (%d,%d)\n",
panel->GetName(), x, y, x + offsetX, y + offsetY, offsetX, offsetY );
#endif
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Resizes windows to fit completely on-screen (for 1280x1024), and
// centers them on the screen. Sub-controls are also resized and moved.
//-----------------------------------------------------------------------------
void LayoutBackgroundPanel( EditablePanel *pWindow )
{
if ( !pWindow )
return;
int screenW, screenH;
GetHudSize( screenW, screenH );
int wide, tall;
pWindow->GetSize( wide, tall );
int offsetX = 0;
int offsetY = 0;
// Slide everything over to the center
pWindow->SetBounds( 0, 0, screenW, screenH );
if ( wide != screenW || tall != screenH )
{
wide = GetAlternateProportionalValueFromScaled(pWindow->GetScheme(), wide);
tall = GetAlternateProportionalValueFromScaled(pWindow->GetScheme(), tall);
offsetX = (screenW - wide)/2;
offsetY = (screenH - tall)/2;
ResizeWindowControls( pWindow, tall, wide, offsetX, offsetY );
}
// now that the panels are moved/resized, look for some bg panels, and re-align them
FixupBackgroundPanels( pWindow, offsetX, offsetY );
}
//-----------------------------------------------------------------------------

View File

@ -1,43 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef CSBACKGROUND_H
#define CSBACKGROUND_H
#include <vgui_controls/Frame.h>
#include <vgui_controls/EditablePanel.h>
//-----------------------------------------------------------------------------
// Purpose: Creates background image panels
//-----------------------------------------------------------------------------
void CreateBackground( vgui::EditablePanel *pWindow );
//-----------------------------------------------------------------------------
// Purpose: Resizes windows to fit completely on-screen (for 1280x1024), and
// centers them on the screen. Sub-controls are also resized and moved.
//-----------------------------------------------------------------------------
void LayoutBackgroundPanel( vgui::EditablePanel *pWindow );
//-----------------------------------------------------------------------------
// Purpose: Sets colors etc for background image panels
//-----------------------------------------------------------------------------
void ApplyBackgroundSchemeSettings( vgui::EditablePanel *pWindow, vgui::IScheme *pScheme );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ResizeWindowControls( vgui::EditablePanel *pWindow, int tall, int wide, int offsetX, int offsetY );
//-----------------------------------------------------------------------------
// Purpose: transform a standard scaled value into one that is scaled based the minimum
// of the horizontal and vertical ratios
//-----------------------------------------------------------------------------
int GetAlternateProportionalValueFromScaled( vgui::HScheme hScheme, int scaledValue );
//-----------------------------------------------------------------------------
#endif // CSBACKGROUND_H

View File

@ -1,653 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hud.h"
#include "hl2mpclientscoreboard.h"
#include "c_team.h"
#include "c_playerresource.h"
#include "c_hl2mp_player.h"
#include "hl2mp_gamerules.h"
#include <KeyValues.h>
#include <vgui/IScheme.h>
#include <vgui/ILocalize.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include <vgui_controls/SectionedListPanel.h>
#include "voice_status.h"
using namespace vgui;
#define TEAM_MAXCOUNT 5
// id's of sections used in the scoreboard
enum EScoreboardSections
{
SCORESECTION_COMBINE = 1,
SCORESECTION_REBELS = 2,
SCORESECTION_FREEFORALL = 3,
SCORESECTION_SPECTATOR = 4
};
const int NumSegments = 7;
static int coord[NumSegments+1] = {
0,
1,
2,
3,
4,
6,
9,
10
};
//-----------------------------------------------------------------------------
// Purpose: Konstructor
//-----------------------------------------------------------------------------
CHL2MPClientScoreBoardDialog::CHL2MPClientScoreBoardDialog(IViewPort *pViewPort):CClientScoreBoardDialog(pViewPort)
{
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CHL2MPClientScoreBoardDialog::~CHL2MPClientScoreBoardDialog()
{
}
//-----------------------------------------------------------------------------
// Purpose: Paint background for rounded corners
//-----------------------------------------------------------------------------
void CHL2MPClientScoreBoardDialog::PaintBackground()
{
m_pPlayerList->SetBgColor( Color(0, 0, 0, 0) );
m_pPlayerList->SetBorder(NULL);
int x1, x2, y1, y2;
surface()->DrawSetColor(m_bgColor);
surface()->DrawSetTextColor(m_bgColor);
int wide, tall;
GetSize( wide, tall );
int i;
// top-left corner --------------------------------------------------------
int xDir = 1;
int yDir = -1;
int xIndex = 0;
int yIndex = NumSegments - 1;
int xMult = 1;
int yMult = 1;
int x = 0;
int y = 0;
for ( i=0; i<NumSegments; ++i )
{
x1 = MIN( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
x2 = MAX( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
y1 = MAX( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
y2 = y + coord[NumSegments];
surface()->DrawFilledRect( x1, y1, x2, y2 );
xIndex += xDir;
yIndex += yDir;
}
// top-right corner -------------------------------------------------------
xDir = 1;
yDir = -1;
xIndex = 0;
yIndex = NumSegments - 1;
x = wide;
y = 0;
xMult = -1;
yMult = 1;
for ( i=0; i<NumSegments; ++i )
{
x1 = MIN( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
x2 = MAX( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
y1 = MAX( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
y2 = y + coord[NumSegments];
surface()->DrawFilledRect( x1, y1, x2, y2 );
xIndex += xDir;
yIndex += yDir;
}
// bottom-right corner ----------------------------------------------------
xDir = 1;
yDir = -1;
xIndex = 0;
yIndex = NumSegments - 1;
x = wide;
y = tall;
xMult = -1;
yMult = -1;
for ( i=0; i<NumSegments; ++i )
{
x1 = MIN( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
x2 = MAX( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
y1 = y - coord[NumSegments];
y2 = MIN( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
surface()->DrawFilledRect( x1, y1, x2, y2 );
xIndex += xDir;
yIndex += yDir;
}
// bottom-left corner -----------------------------------------------------
xDir = 1;
yDir = -1;
xIndex = 0;
yIndex = NumSegments - 1;
x = 0;
y = tall;
xMult = 1;
yMult = -1;
for ( i=0; i<NumSegments; ++i )
{
x1 = MIN( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
x2 = MAX( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
y1 = y - coord[NumSegments];
y2 = MIN( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
surface()->DrawFilledRect( x1, y1, x2, y2 );
xIndex += xDir;
yIndex += yDir;
}
// paint between top left and bottom left ---------------------------------
x1 = 0;
x2 = coord[NumSegments];
y1 = coord[NumSegments];
y2 = tall - coord[NumSegments];
surface()->DrawFilledRect( x1, y1, x2, y2 );
// paint between left and right -------------------------------------------
x1 = coord[NumSegments];
x2 = wide - coord[NumSegments];
y1 = 0;
y2 = tall;
surface()->DrawFilledRect( x1, y1, x2, y2 );
// paint between top right and bottom right -------------------------------
x1 = wide - coord[NumSegments];
x2 = wide;
y1 = coord[NumSegments];
y2 = tall - coord[NumSegments];
surface()->DrawFilledRect( x1, y1, x2, y2 );
}
//-----------------------------------------------------------------------------
// Purpose: Paint border for rounded corners
//-----------------------------------------------------------------------------
void CHL2MPClientScoreBoardDialog::PaintBorder()
{
int x1, x2, y1, y2;
surface()->DrawSetColor(m_borderColor);
surface()->DrawSetTextColor(m_borderColor);
int wide, tall;
GetSize( wide, tall );
int i;
// top-left corner --------------------------------------------------------
int xDir = 1;
int yDir = -1;
int xIndex = 0;
int yIndex = NumSegments - 1;
int xMult = 1;
int yMult = 1;
int x = 0;
int y = 0;
for ( i=0; i<NumSegments; ++i )
{
x1 = MIN( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
x2 = MAX( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
y1 = MIN( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
y2 = MAX( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
surface()->DrawFilledRect( x1, y1, x2, y2 );
xIndex += xDir;
yIndex += yDir;
}
// top-right corner -------------------------------------------------------
xDir = 1;
yDir = -1;
xIndex = 0;
yIndex = NumSegments - 1;
x = wide;
y = 0;
xMult = -1;
yMult = 1;
for ( i=0; i<NumSegments; ++i )
{
x1 = MIN( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
x2 = MAX( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
y1 = MIN( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
y2 = MAX( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
surface()->DrawFilledRect( x1, y1, x2, y2 );
xIndex += xDir;
yIndex += yDir;
}
// bottom-right corner ----------------------------------------------------
xDir = 1;
yDir = -1;
xIndex = 0;
yIndex = NumSegments - 1;
x = wide;
y = tall;
xMult = -1;
yMult = -1;
for ( i=0; i<NumSegments; ++i )
{
x1 = MIN( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
x2 = MAX( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
y1 = MIN( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
y2 = MAX( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
surface()->DrawFilledRect( x1, y1, x2, y2 );
xIndex += xDir;
yIndex += yDir;
}
// bottom-left corner -----------------------------------------------------
xDir = 1;
yDir = -1;
xIndex = 0;
yIndex = NumSegments - 1;
x = 0;
y = tall;
xMult = 1;
yMult = -1;
for ( i=0; i<NumSegments; ++i )
{
x1 = MIN( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
x2 = MAX( x + coord[xIndex]*xMult, x + coord[xIndex+1]*xMult );
y1 = MIN( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
y2 = MAX( y + coord[yIndex]*yMult, y + coord[yIndex+1]*yMult );
surface()->DrawFilledRect( x1, y1, x2, y2 );
xIndex += xDir;
yIndex += yDir;
}
// top --------------------------------------------------------------------
x1 = coord[NumSegments];
x2 = wide - coord[NumSegments];
y1 = 0;
y2 = 1;
surface()->DrawFilledRect( x1, y1, x2, y2 );
// bottom -----------------------------------------------------------------
x1 = coord[NumSegments];
x2 = wide - coord[NumSegments];
y1 = tall - 1;
y2 = tall;
surface()->DrawFilledRect( x1, y1, x2, y2 );
// left -------------------------------------------------------------------
x1 = 0;
x2 = 1;
y1 = coord[NumSegments];
y2 = tall - coord[NumSegments];
surface()->DrawFilledRect( x1, y1, x2, y2 );
// right ------------------------------------------------------------------
x1 = wide - 1;
x2 = wide;
y1 = coord[NumSegments];
y2 = tall - coord[NumSegments];
surface()->DrawFilledRect( x1, y1, x2, y2 );
}
//-----------------------------------------------------------------------------
// Purpose: Apply scheme settings
//-----------------------------------------------------------------------------
void CHL2MPClientScoreBoardDialog::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
m_bgColor = GetSchemeColor("SectionedListPanel.BgColor", GetBgColor(), pScheme);
m_borderColor = pScheme->GetColor( "FgColor", Color( 0, 0, 0, 0 ) );
SetBgColor( Color(0, 0, 0, 0) );
SetBorder( pScheme->GetBorder( "BaseBorder" ) );
}
//-----------------------------------------------------------------------------
// Purpose: sets up base sections
//-----------------------------------------------------------------------------
void CHL2MPClientScoreBoardDialog::InitScoreboardSections()
{
m_pPlayerList->SetBgColor( Color(0, 0, 0, 0) );
m_pPlayerList->SetBorder(NULL);
// fill out the structure of the scoreboard
AddHeader();
if ( HL2MPRules()->IsTeamplay() )
{
// add the team sections
AddSection( TYPE_TEAM, TEAM_COMBINE );
AddSection( TYPE_TEAM, TEAM_REBELS );
}
else
{
AddSection( TYPE_TEAM, TEAM_UNASSIGNED );
}
AddSection( TYPE_TEAM, TEAM_SPECTATOR );
}
//-----------------------------------------------------------------------------
// Purpose: resets the scoreboard team info
//-----------------------------------------------------------------------------
void CHL2MPClientScoreBoardDialog::UpdateTeamInfo()
{
if ( g_PR == NULL )
return;
int iNumPlayersInGame = 0;
for ( int j = 1; j <= gpGlobals->maxClients; j++ )
{
if ( g_PR->IsConnected( j ) )
{
iNumPlayersInGame++;
}
}
// update the team sections in the scoreboard
for ( int i = TEAM_SPECTATOR; i < TEAM_MAXCOUNT; i++ )
{
wchar_t *teamName = NULL;
int sectionID = 0;
C_Team *team = GetGlobalTeam(i);
if ( team )
{
sectionID = GetSectionFromTeamNumber( i );
// update team name
wchar_t name[64];
wchar_t string1[1024];
wchar_t wNumPlayers[6];
if ( HL2MPRules()->IsTeamplay() == false )
{
_snwprintf( wNumPlayers, ARRAYSIZE(wNumPlayers), L"%i", iNumPlayersInGame );
#ifdef WIN32
_snwprintf( name, ARRAYSIZE(name), L"%s", g_pVGuiLocalize->Find("#ScoreBoard_Deathmatch") );
#else
_snwprintf( name, ARRAYSIZE(name), L"%S", g_pVGuiLocalize->Find("#ScoreBoard_Deathmatch") );
#endif
teamName = name;
if ( iNumPlayersInGame == 1)
{
g_pVGuiLocalize->ConstructString( string1, sizeof(string1), g_pVGuiLocalize->Find("#ScoreBoard_Player"), 2, teamName, wNumPlayers );
}
else
{
g_pVGuiLocalize->ConstructString( string1, sizeof(string1), g_pVGuiLocalize->Find("#ScoreBoard_Players"), 2, teamName, wNumPlayers );
}
}
else
{
_snwprintf(wNumPlayers, ARRAYSIZE(wNumPlayers), L"%i", team->Get_Number_Players());
if (!teamName && team)
{
g_pVGuiLocalize->ConvertANSIToUnicode(team->Get_Name(), name, sizeof(name));
teamName = name;
}
if (team->Get_Number_Players() == 1)
{
g_pVGuiLocalize->ConstructString( string1, sizeof(string1), g_pVGuiLocalize->Find("#ScoreBoard_Player"), 2, teamName, wNumPlayers );
}
else
{
g_pVGuiLocalize->ConstructString( string1, sizeof(string1), g_pVGuiLocalize->Find("#ScoreBoard_Players"), 2, teamName, wNumPlayers );
}
// update stats
wchar_t val[6];
V_snwprintf(val, ARRAYSIZE(val), L"%d", team->Get_Score());
m_pPlayerList->ModifyColumn(sectionID, "frags", val);
if (team->Get_Ping() < 1)
{
m_pPlayerList->ModifyColumn(sectionID, "ping", L"");
}
else
{
V_snwprintf(val, ARRAYSIZE(val), L"%d", team->Get_Ping());
m_pPlayerList->ModifyColumn(sectionID, "ping", val);
}
}
m_pPlayerList->ModifyColumn(sectionID, "name", string1);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: adds the top header of the scoreboars
//-----------------------------------------------------------------------------
void CHL2MPClientScoreBoardDialog::AddHeader()
{
// add the top header
m_pPlayerList->AddSection(0, "");
m_pPlayerList->SetSectionAlwaysVisible(0);
HFont hFallbackFont = scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultVerySmallFallBack", false );
m_pPlayerList->AddColumnToSection(0, "name", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_NAME_WIDTH ), hFallbackFont );
m_pPlayerList->AddColumnToSection(0, "class", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_CLASS_WIDTH ) );
m_pPlayerList->AddColumnToSection(0, "frags", "#PlayerScore", 0 | SectionedListPanel::COLUMN_RIGHT, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_SCORE_WIDTH ) );
m_pPlayerList->AddColumnToSection(0, "deaths", "#PlayerDeath", 0 | SectionedListPanel::COLUMN_RIGHT, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_DEATH_WIDTH ) );
m_pPlayerList->AddColumnToSection(0, "ping", "#PlayerPing", 0 | SectionedListPanel::COLUMN_RIGHT, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_PING_WIDTH ) );
// m_pPlayerList->AddColumnToSection(0, "voice", "#PlayerVoice", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::HEADER_TEXT| SectionedListPanel::COLUMN_CENTER, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_VOICE_WIDTH ) );
// m_pPlayerList->AddColumnToSection(0, "tracker", "#PlayerTracker", SectionedListPanel::COLUMN_IMAGE | SectionedListPanel::HEADER_TEXT, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_FRIENDS_WIDTH ) );
}
//-----------------------------------------------------------------------------
// Purpose: Adds a new section to the scoreboard (i.e the team header)
//-----------------------------------------------------------------------------
void CHL2MPClientScoreBoardDialog::AddSection(int teamType, int teamNumber)
{
HFont hFallbackFont = scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultVerySmallFallBack", false );
int sectionID = GetSectionFromTeamNumber( teamNumber );
if ( teamType == TYPE_TEAM )
{
m_pPlayerList->AddSection(sectionID, "", StaticPlayerSortFunc);
// setup the columns
m_pPlayerList->AddColumnToSection(sectionID, "name", "", 0, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_NAME_WIDTH ), hFallbackFont );
m_pPlayerList->AddColumnToSection(sectionID, "class", "" , 0, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_CLASS_WIDTH ) );
m_pPlayerList->AddColumnToSection(sectionID, "frags", "", SectionedListPanel::COLUMN_RIGHT, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_SCORE_WIDTH ) );
m_pPlayerList->AddColumnToSection(sectionID, "deaths", "", SectionedListPanel::COLUMN_RIGHT, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_DEATH_WIDTH ) );
m_pPlayerList->AddColumnToSection(sectionID, "ping", "", SectionedListPanel::COLUMN_RIGHT, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_PING_WIDTH ) );
// set the section to have the team color
if ( teamNumber )
{
if ( GameResources() )
m_pPlayerList->SetSectionFgColor(sectionID, GameResources()->GetTeamColor(teamNumber));
}
m_pPlayerList->SetSectionAlwaysVisible(sectionID);
}
else if ( teamType == TYPE_SPECTATORS )
{
m_pPlayerList->AddSection(sectionID, "");
m_pPlayerList->AddColumnToSection(sectionID, "name", "#Spectators", 0, scheme()->GetProportionalScaledValueEx( GetScheme(), CSTRIKE_NAME_WIDTH ), hFallbackFont );
m_pPlayerList->AddColumnToSection(sectionID, "class", "" , 0, scheme()->GetProportionalScaledValueEx( GetScheme(), 100 ) );
}
}
int CHL2MPClientScoreBoardDialog::GetSectionFromTeamNumber( int teamNumber )
{
switch ( teamNumber )
{
case TEAM_COMBINE:
return SCORESECTION_COMBINE;
case TEAM_REBELS:
return SCORESECTION_REBELS;
case TEAM_SPECTATOR:
return SCORESECTION_SPECTATOR;
default:
return SCORESECTION_FREEFORALL;
}
return SCORESECTION_FREEFORALL;
}
//-----------------------------------------------------------------------------
// Purpose: Adds a new row to the scoreboard, from the playerinfo structure
//-----------------------------------------------------------------------------
bool CHL2MPClientScoreBoardDialog::GetPlayerScoreInfo(int playerIndex, KeyValues *kv)
{
kv->SetInt("playerIndex", playerIndex);
kv->SetInt("team", g_PR->GetTeam( playerIndex ) );
kv->SetString("name", g_PR->GetPlayerName(playerIndex) );
kv->SetInt("deaths", g_PR->GetDeaths( playerIndex ));
kv->SetInt("frags", g_PR->GetPlayerScore( playerIndex ));
kv->SetString("class", "");
if (g_PR->GetPing( playerIndex ) < 1)
{
if ( g_PR->IsFakePlayer( playerIndex ) )
{
kv->SetString("ping", "BOT");
}
else
{
kv->SetString("ping", "");
}
}
else
{
kv->SetInt("ping", g_PR->GetPing( playerIndex ));
}
return true;
}
enum {
MAX_PLAYERS_PER_TEAM = 16,
MAX_SCOREBOARD_PLAYERS = 32
};
struct PlayerScoreInfo
{
int index;
int frags;
int deaths;
bool important;
bool alive;
};
int PlayerScoreInfoSort( const PlayerScoreInfo *p1, const PlayerScoreInfo *p2 )
{
// check local
if ( p1->important )
return -1;
if ( p2->important )
return 1;
// check alive
if ( p1->alive && !p2->alive )
return -1;
if ( p2->alive && !p1->alive )
return 1;
// check frags
if ( p1->frags > p2->frags )
return -1;
if ( p2->frags > p1->frags )
return 1;
// check deaths
if ( p1->deaths < p2->deaths )
return -1;
if ( p2->deaths < p1->deaths )
return 1;
// check index
if ( p1->index < p2->index )
return -1;
return 1;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPClientScoreBoardDialog::UpdatePlayerInfo()
{
m_iSectionId = 0; // 0'th row is a header
int selectedRow = -1;
int i;
CBasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
if ( !pPlayer || !g_PR )
return;
// walk all the players and make sure they're in the scoreboard
for ( i = 1; i <= gpGlobals->maxClients; i++ )
{
bool shouldShow = g_PR->IsConnected( i );
if ( shouldShow )
{
// add the player to the list
KeyValues *playerData = new KeyValues("data");
GetPlayerScoreInfo( i, playerData );
int itemID = FindItemIDForPlayerIndex( i );
int sectionID = GetSectionFromTeamNumber( g_PR->GetTeam( i ) );
if (itemID == -1)
{
// add a new row
itemID = m_pPlayerList->AddItem( sectionID, playerData );
}
else
{
// modify the current row
m_pPlayerList->ModifyItem( itemID, sectionID, playerData );
}
if ( i == pPlayer->entindex() )
{
selectedRow = itemID; // this is the local player, hilight this row
}
// set the row color based on the players team
m_pPlayerList->SetItemFgColor( itemID, g_PR->GetTeamColor( g_PR->GetTeam( i ) ) );
playerData->deleteThis();
}
else
{
// remove the player
int itemID = FindItemIDForPlayerIndex( i );
if (itemID != -1)
{
m_pPlayerList->RemoveItem(itemID);
}
}
}
if ( selectedRow != -1 )
{
m_pPlayerList->SetSelectedItem(selectedRow);
}
}

View File

@ -1,63 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef CHL2MPCLIENTSCOREBOARDDIALOG_H
#define CHL2MPCLIENTSCOREBOARDDIALOG_H
#ifdef _WIN32
#pragma once
#endif
#include <clientscoreboarddialog.h>
//-----------------------------------------------------------------------------
// Purpose: Game ScoreBoard
//-----------------------------------------------------------------------------
class CHL2MPClientScoreBoardDialog : public CClientScoreBoardDialog
{
private:
DECLARE_CLASS_SIMPLE(CHL2MPClientScoreBoardDialog, CClientScoreBoardDialog);
public:
CHL2MPClientScoreBoardDialog(IViewPort *pViewPort);
~CHL2MPClientScoreBoardDialog();
protected:
// scoreboard overrides
virtual void InitScoreboardSections();
virtual void UpdateTeamInfo();
virtual bool GetPlayerScoreInfo(int playerIndex, KeyValues *outPlayerInfo);
virtual void UpdatePlayerInfo();
// vgui overrides for rounded corner background
virtual void PaintBackground();
virtual void PaintBorder();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
private:
virtual void AddHeader(); // add the start header of the scoreboard
virtual void AddSection(int teamType, int teamNumber); // add a new section header for a team
int GetSectionFromTeamNumber( int teamNumber );
enum
{
CSTRIKE_NAME_WIDTH = 320,
CSTRIKE_CLASS_WIDTH = 56,
CSTRIKE_SCORE_WIDTH = 40,
CSTRIKE_DEATH_WIDTH = 46,
CSTRIKE_PING_WIDTH = 46,
// CSTRIKE_VOICE_WIDTH = 40,
// CSTRIKE_FRIENDS_WIDTH = 24,
};
// rounded corners
Color m_bgColor;
Color m_borderColor;
};
#endif // CHL2MPCLIENTSCOREBOARDDIALOG_H

View File

@ -1,174 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hl2mptextwindow.h"
#include "backgroundpanel.h"
#include <cdll_client_int.h>
#include <vgui/IScheme.h>
#include <vgui/ILocalize.h>
#include <vgui/ISurface.h>
#include <filesystem.h>
#include <KeyValues.h>
#include <convar.h>
#include <vgui_controls/ImageList.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/BuildGroup.h>
#include "IGameUIFuncs.h" // for key bindings
#include <igameresources.h>
extern IGameUIFuncs *gameuifuncs; // for key binding details
#include <game/client/iviewport.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CHL2MPTextWindow::CHL2MPTextWindow(IViewPort *pViewPort) : CTextWindow( pViewPort )
{
SetProportional( true );
m_iScoreBoardKey = BUTTON_CODE_INVALID; // this is looked up in Activate()
CreateBackground( this );
m_backgroundLayoutFinished = false;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CHL2MPTextWindow::~CHL2MPTextWindow()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPTextWindow::Update()
{
BaseClass::Update();
m_pOK->RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPTextWindow::SetVisible(bool state)
{
BaseClass::SetVisible(state);
if ( state )
{
m_pOK->RequestFocus();
}
}
//-----------------------------------------------------------------------------
// Purpose: shows the text window
//-----------------------------------------------------------------------------
void CHL2MPTextWindow::ShowPanel(bool bShow)
{
if ( bShow )
{
// get key binding if shown
if ( m_iScoreBoardKey == BUTTON_CODE_INVALID ) // you need to lookup the jump key AFTER the engine has loaded
{
m_iScoreBoardKey = gameuifuncs->GetButtonCodeForBind( "showscores" );
}
}
BaseClass::ShowPanel( bShow );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPTextWindow::OnKeyCodePressed(KeyCode code)
{
if ( m_iScoreBoardKey != BUTTON_CODE_INVALID && m_iScoreBoardKey == code )
{
gViewPortInterface->ShowPanel( PANEL_SCOREBOARD, true );
gViewPortInterface->PostMessageToPanel( PANEL_SCOREBOARD, new KeyValues( "PollHideCode", "code", code ) );
}
else
{
BaseClass::OnKeyCodePressed( code );
}
}
//-----------------------------------------------------------------------------
// Purpose: The CS background is painted by image panels, so we should do nothing
//-----------------------------------------------------------------------------
void CHL2MPTextWindow::PaintBackground()
{
}
//-----------------------------------------------------------------------------
// Purpose: Scale / center the window
//-----------------------------------------------------------------------------
void CHL2MPTextWindow::PerformLayout()
{
BaseClass::PerformLayout();
// stretch the window to fullscreen
if ( !m_backgroundLayoutFinished )
LayoutBackgroundPanel( this );
m_backgroundLayoutFinished = true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPTextWindow::ApplySchemeSettings( vgui::IScheme *pScheme )
{
BaseClass::ApplySchemeSettings( pScheme );
ApplyBackgroundSchemeSettings( this, pScheme );
}
CHL2MPSpectatorGUI::CHL2MPSpectatorGUI(IViewPort *pViewPort) : CSpectatorGUI(pViewPort)
{
}
bool CHL2MPSpectatorGUI::NeedsUpdate( void )
{
if ( !C_BasePlayer::GetLocalPlayer() )
return false;
if ( m_nLastSpecMode != C_BasePlayer::GetLocalPlayer()->GetObserverMode() )
return true;
if ( m_nLastSpecTarget != C_BasePlayer::GetLocalPlayer()->GetObserverTarget() )
return true;
return BaseClass::NeedsUpdate();
}
void CHL2MPSpectatorGUI::Update()
{
BaseClass::Update();
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
if( pLocalPlayer )
{
m_nLastSpecMode = pLocalPlayer->GetObserverMode();
m_nLastSpecTarget = pLocalPlayer->GetObserverTarget();
}
}

View File

@ -1,67 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef CSTEXTWINDOW_H
#define CSTEXTWINDOW_H
#ifdef _WIN32
#pragma once
#endif
#include "vguitextwindow.h"
#include <spectatorgui.h>
//-----------------------------------------------------------------------------
// Purpose: displays the MOTD
//-----------------------------------------------------------------------------
class CHL2MPTextWindow : public CTextWindow
{
private:
DECLARE_CLASS_SIMPLE( CHL2MPTextWindow, CTextWindow );
public:
CHL2MPTextWindow(IViewPort *pViewPort);
virtual ~CHL2MPTextWindow();
virtual void Update();
virtual void SetVisible(bool state);
virtual void ShowPanel( bool bShow );
virtual void OnKeyCodePressed(vgui::KeyCode code);
protected:
ButtonCode_t m_iScoreBoardKey;
// Background panel -------------------------------------------------------
public:
virtual void PaintBackground();
virtual void PerformLayout();
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
bool m_backgroundLayoutFinished;
// End background panel ---------------------------------------------------
};
class CHL2MPSpectatorGUI : public CSpectatorGUI
{
private:
DECLARE_CLASS_SIMPLE( CHL2MPSpectatorGUI, CSpectatorGUI );
public:
CHL2MPSpectatorGUI( IViewPort *pViewPort );
virtual void Update( void );
virtual bool NeedsUpdate( void );
protected:
int m_nLastSpecMode;
CBaseEntity *m_nLastSpecTarget;
};
#endif // CSTEXTWINDOW_H

View File

@ -1,365 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "grenade_satchel.h"
#include "player.h"
#include "soundenvelope.h"
#include "engine/IEngineSound.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ConVar sk_plr_dmg_satchel ( "sk_plr_dmg_satchel","0");
ConVar sk_npc_dmg_satchel ( "sk_npc_dmg_satchel","0");
ConVar sk_satchel_radius ( "sk_satchel_radius","0");
BEGIN_DATADESC( CSatchelCharge )
DEFINE_SOUNDPATCH( m_soundSlide ),
DEFINE_FIELD( m_flSlideVolume, FIELD_FLOAT ),
DEFINE_FIELD( m_flNextBounceSoundTime, FIELD_TIME ),
DEFINE_FIELD( m_bInAir, FIELD_BOOLEAN ),
DEFINE_FIELD( m_vLastPosition, FIELD_POSITION_VECTOR ),
DEFINE_FIELD( m_pMyWeaponSLAM, FIELD_CLASSPTR ),
DEFINE_FIELD( m_bIsAttached, FIELD_BOOLEAN ),
// Function Pointers
DEFINE_FUNCTION( SatchelTouch ),
DEFINE_FUNCTION( SatchelThink ),
DEFINE_FUNCTION( SatchelUse ),
END_DATADESC()
LINK_ENTITY_TO_CLASS( npc_satchel, CSatchelCharge );
//=========================================================
// Deactivate - do whatever it is we do to an orphaned
// satchel when we don't want it in the world anymore.
//=========================================================
void CSatchelCharge::Deactivate( void )
{
AddSolidFlags( FSOLID_NOT_SOLID );
UTIL_Remove( this );
}
void CSatchelCharge::Spawn( void )
{
Precache( );
// motor
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
SetSolid( SOLID_BBOX );
SetCollisionGroup( COLLISION_GROUP_PROJECTILE );
SetModel( "models/Weapons/w_slam.mdl" );
UTIL_SetSize(this, Vector( -6, -6, -2), Vector(6, 6, 2));
SetTouch( SatchelTouch );
SetUse( SatchelUse );
SetThink( SatchelThink );
SetNextThink( gpGlobals->curtime + 0.1f );
m_flDamage = sk_plr_dmg_satchel.GetFloat();
m_DmgRadius = sk_satchel_radius.GetFloat();
m_takedamage = DAMAGE_YES;
m_iHealth = 1;
SetGravity( UTIL_ScaleForGravity( 560 ) ); // slightly lower gravity
SetFriction( 1.0 );
SetSequence( 1 );
m_bIsAttached = false;
m_bInAir = true;
m_flSlideVolume = -1.0;
m_flNextBounceSoundTime = 0;
m_vLastPosition = vec3_origin;
InitSlideSound();
}
//-----------------------------------------------------------------------------
void CSatchelCharge::InitSlideSound(void)
{
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
CPASAttenuationFilter filter( this );
m_soundSlide = controller.SoundCreate( filter, entindex(), CHAN_STATIC, "SatchelCharge.Slide", ATTN_NORM );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CSatchelCharge::KillSlideSound(void)
{
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
controller.CommandClear( m_soundSlide );
controller.SoundFadeOut( m_soundSlide, 0.0 );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CSatchelCharge::SatchelUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
KillSlideSound();
SetThink( Detonate );
SetNextThink( gpGlobals->curtime );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CSatchelCharge::SatchelTouch( CBaseEntity *pOther )
{
Assert( pOther );
if ( !pOther->IsSolid() )
return;
// If successfully thrown and touching the
// NPC that released this grenade, pick it up
if ( pOther == GetThrower() && GetOwnerEntity() == NULL )
{
CBasePlayer *pPlayer = ToBasePlayer( m_pMyWeaponSLAM->GetOwner() );
if (pPlayer)
{
// Give the player ammo
pPlayer->GiveAmmo(1, m_pMyWeaponSLAM->m_iSecondaryAmmoType);
CPASAttenuationFilter filter( pPlayer, "SatchelCharge.Pickup" );
EmitSound( filter, pPlayer->entindex(), "SatchelCharge.Pickup" );
m_bIsLive = false;
// Take weapon out of detonate mode if necessary
if (!m_pMyWeaponSLAM->AnyUndetonatedCharges())
{
m_pMyWeaponSLAM->m_bDetonatorArmed = false;
m_pMyWeaponSLAM->m_bNeedDetonatorHolster = true;
// Put detonator away right away
m_pMyWeaponSLAM->SetWeaponIdleTime( gpGlobals->curtime );
}
// Kill any sliding sound
KillSlideSound();
// Remove satchel charge from world
UTIL_Remove( this );
return;
}
}
StudioFrameAdvance( );
// Is it attached to a wall?
if (m_bIsAttached)
{
return;
}
SetGravity( 1 );// normal gravity now
// HACKHACK - On ground isn't always set, so look for ground underneath
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,10), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
if ( tr.fraction < 1.0 )
{
// add a bit of static friction
SetAbsVelocity( GetAbsVelocity() * 0.85 );
SetLocalAngularVelocity( GetLocalAngularVelocity() * 0.8 );
}
UpdateSlideSound();
if (m_bInAir)
{
BounceSound();
m_bInAir = false;
}
}
void CSatchelCharge::UpdateSlideSound( void )
{
if (!m_soundSlide)
{
return;
}
float volume = GetAbsVelocity().Length2D()/1000;
if (volume < 0.01 && m_soundSlide)
{
KillSlideSound();
return;
}
// HACKHACK - On ground isn't always set, so look for ground underneath
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,10), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr );
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
if ( tr.fraction < 1.0 )
{
if (m_flSlideVolume == -1.0)
{
controller.CommandClear( m_soundSlide );
controller.Play( m_soundSlide, 1.0, 100 );
m_flSlideVolume = 1.0;
}
else
{
float volume = GetAbsVelocity().Length()/1000;
if ( volume < m_flSlideVolume )
{
m_flSlideVolume = volume;
controller.CommandClear( m_soundSlide );
controller.SoundChangeVolume( m_soundSlide, volume, 0.1 );
}
}
}
else
{
controller.CommandClear( m_soundSlide );
controller.SoundChangeVolume( m_soundSlide, 0.0, 0.01 );
m_flSlideVolume = -1.0;
m_bInAir = true;
return;
}
}
void CSatchelCharge::SatchelThink( void )
{
// If attached resize so player can pick up off wall
if (m_bIsAttached)
{
UTIL_SetSize(this, Vector( -2, -2, -6), Vector(2, 2, 6));
}
UpdateSlideSound();
// See if I can lose my owner (has dropper moved out of way?)
// Want do this so owner can shoot the satchel charge
if (GetOwnerEntity())
{
trace_t tr;
Vector vUpABit = GetAbsOrigin();
vUpABit.z += 5.0;
CBaseEntity* saveOwner = GetOwnerEntity();
SetOwnerEntity( NULL );
UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr );
if ( tr.startsolid || tr.fraction != 1.0 )
{
SetOwnerEntity( saveOwner );
}
}
// Bounce movement code gets this think stuck occasionally so check if I've
// succeeded in moving, otherwise kill my motions.
else if ((GetAbsOrigin() - m_vLastPosition).LengthSqr()<1)
{
SetAbsVelocity( vec3_origin );
QAngle angVel = GetLocalAngularVelocity();
angVel.y = 0;
SetLocalAngularVelocity( angVel );
// Kill any remaining sound
KillSlideSound();
// Clear think function
SetThink(NULL);
return;
}
m_vLastPosition= GetAbsOrigin();
StudioFrameAdvance( );
SetNextThink( gpGlobals->curtime + 0.1f );
if (!IsInWorld())
{
// Kill any remaining sound
KillSlideSound();
UTIL_Remove( this );
return;
}
// Is it attached to a wall?
if (m_bIsAttached)
{
return;
}
Vector vecNewVel = GetAbsVelocity();
if (GetWaterLevel() == 3)
{
SetMoveType( MOVETYPE_FLY );
vecNewVel *= 0.8;
vecNewVel.z += 8;
SetLocalAngularVelocity( GetLocalAngularVelocity() * 0.9 );
}
else if (GetWaterLevel() == 0)
{
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
}
else
{
vecNewVel.z -= 8;
}
SetAbsVelocity( vecNewVel );
}
void CSatchelCharge::Precache( void )
{
PrecacheModel("models/Weapons/w_slam.mdl");
PrecacheScriptSound( "SatchelCharge.Pickup" );
PrecacheScriptSound( "SatchelCharge.Bounce" );
PrecacheScriptSound( "SatchelCharge.Slide" );
}
void CSatchelCharge::BounceSound( void )
{
if (gpGlobals->curtime > m_flNextBounceSoundTime)
{
EmitSound( "SatchelCharge.Bounce" );
m_flNextBounceSoundTime = gpGlobals->curtime + 0.1;
}
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input :
// Output :
//-----------------------------------------------------------------------------
CSatchelCharge::CSatchelCharge(void)
{
m_vLastPosition.Init();
m_pMyWeaponSLAM = NULL;
}
CSatchelCharge::~CSatchelCharge(void)
{
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
controller.SoundDestroy( m_soundSlide );
}

View File

@ -1,57 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Satchel Charge
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#ifndef SATCHEL_H
#define SATCHEL_H
#ifdef _WIN32
#pragma once
#endif
#include "basegrenade_shared.h"
#include "hl2mp/weapon_slam.h"
class CSoundPatch;
class CSatchelCharge : public CBaseGrenade
{
public:
DECLARE_CLASS( CSatchelCharge, CBaseGrenade );
void Spawn( void );
void Precache( void );
void BounceSound( void );
void UpdateSlideSound( void );
void KillSlideSound(void);
void SatchelTouch( CBaseEntity *pOther );
void SatchelThink( void );
void SatchelUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
CSoundPatch* m_soundSlide;
float m_flSlideVolume;
float m_flNextBounceSoundTime;
bool m_bInAir;
Vector m_vLastPosition;
public:
CWeapon_SLAM* m_pMyWeaponSLAM; // Who shot me..
bool m_bIsAttached;
void Deactivate( void );
CSatchelCharge();
~CSatchelCharge();
DECLARE_DATADESC();
private:
void InitSlideSound(void);
};
#endif //SATCHEL_H

View File

@ -1,266 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Implements the tripmine grenade.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "beam_shared.h"
#include "shake.h"
#include "grenade_tripmine.h"
#include "vstdlib/random.h"
#include "engine/IEngineSound.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
extern const char* g_pModelNameLaser;
ConVar sk_plr_dmg_tripmine ( "sk_plr_dmg_tripmine","0");
ConVar sk_npc_dmg_tripmine ( "sk_npc_dmg_tripmine","0");
ConVar sk_tripmine_radius ( "sk_tripmine_radius","0");
LINK_ENTITY_TO_CLASS( npc_tripmine, CTripmineGrenade );
BEGIN_DATADESC( CTripmineGrenade )
DEFINE_FIELD( m_hOwner, FIELD_EHANDLE ),
DEFINE_FIELD( m_flPowerUp, FIELD_TIME ),
DEFINE_FIELD( m_vecDir, FIELD_VECTOR ),
DEFINE_FIELD( m_vecEnd, FIELD_POSITION_VECTOR ),
DEFINE_FIELD( m_flBeamLength, FIELD_FLOAT ),
DEFINE_FIELD( m_pBeam, FIELD_CLASSPTR ),
DEFINE_FIELD( m_posOwner, FIELD_POSITION_VECTOR ),
DEFINE_FIELD( m_angleOwner, FIELD_VECTOR ),
// Function Pointers
DEFINE_FUNCTION( WarningThink ),
DEFINE_FUNCTION( PowerupThink ),
DEFINE_FUNCTION( BeamBreakThink ),
DEFINE_FUNCTION( DelayDeathThink ),
END_DATADESC()
CTripmineGrenade::CTripmineGrenade()
{
m_vecDir.Init();
m_vecEnd.Init();
m_posOwner.Init();
m_angleOwner.Init();
}
void CTripmineGrenade::Spawn( void )
{
Precache( );
// motor
SetMoveType( MOVETYPE_FLY );
SetSolid( SOLID_BBOX );
AddSolidFlags( FSOLID_NOT_SOLID );
SetModel( "models/Weapons/w_slam.mdl" );
m_flCycle = 0;
m_nBody = 3;
m_flDamage = sk_plr_dmg_tripmine.GetFloat();
m_DmgRadius = sk_tripmine_radius.GetFloat();
ResetSequenceInfo( );
m_flPlaybackRate = 0;
UTIL_SetSize(this, Vector( -4, -4, -2), Vector(4, 4, 2));
m_flPowerUp = gpGlobals->curtime + 2.0;
SetThink( PowerupThink );
SetNextThink( gpGlobals->curtime + 0.2 );
m_takedamage = DAMAGE_YES;
m_iHealth = 1;
EmitSound( "TripmineGrenade.Charge" );
// Tripmine sits at 90 on wall so rotate back to get m_vecDir
QAngle angles = GetLocalAngles();
angles.x -= 90;
AngleVectors( angles, &m_vecDir );
m_vecEnd = GetLocalOrigin() + m_vecDir * 2048;
}
void CTripmineGrenade::Precache( void )
{
PrecacheModel("models/Weapons/w_slam.mdl");
PrecacheScriptSound( "TripmineGrenade.Charge" );
PrecacheScriptSound( "TripmineGrenade.PowerUp" );
PrecacheScriptSound( "TripmineGrenade.StopSound" );
PrecacheScriptSound( "TripmineGrenade.Activate" );
PrecacheScriptSound( "TripmineGrenade.ShootRope" );
PrecacheScriptSound( "TripmineGrenade.Hook" );
}
void CTripmineGrenade::WarningThink( void )
{
// set to power up
SetThink( PowerupThink );
SetNextThink( gpGlobals->curtime + 1.0f );
}
void CTripmineGrenade::PowerupThink( void )
{
if (gpGlobals->curtime > m_flPowerUp)
{
MakeBeam( );
RemoveSolidFlags( FSOLID_NOT_SOLID );
m_bIsLive = true;
// play enabled sound
EmitSound( "TripmineGrenade.PowerUp" );;
}
SetNextThink( gpGlobals->curtime + 0.1f );
}
void CTripmineGrenade::KillBeam( void )
{
if ( m_pBeam )
{
UTIL_Remove( m_pBeam );
m_pBeam = NULL;
}
}
void CTripmineGrenade::MakeBeam( void )
{
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), m_vecEnd, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
m_flBeamLength = tr.fraction;
// If I hit a living thing, send the beam through me so it turns on briefly
// and then blows the living thing up
CBaseEntity *pEntity = tr.m_pEnt;
CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pEntity );
// Draw length is not the beam length if entity is in the way
float drawLength = tr.fraction;
if (pBCC)
{
SetOwnerEntity( pBCC );
UTIL_TraceLine( GetAbsOrigin(), m_vecEnd, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
m_flBeamLength = tr.fraction;
SetOwnerEntity( NULL );
}
// set to follow laser spot
SetThink( BeamBreakThink );
// Delay first think slightly so beam has time
// to appear if person right in front of it
SetNextThink( gpGlobals->curtime + 1.0f );
Vector vecTmpEnd = GetLocalOrigin() + m_vecDir * 2048 * drawLength;
m_pBeam = CBeam::BeamCreate( g_pModelNameLaser, 1.0 );
m_pBeam->PointEntInit( vecTmpEnd, this );
m_pBeam->SetColor( 0, 214, 198 );
m_pBeam->SetScrollRate( 25.6 );
m_pBeam->SetBrightness( 64 );
}
void CTripmineGrenade::BeamBreakThink( void )
{
// See if I can go solid yet (has dropper moved out of way?)
if (IsSolidFlagSet( FSOLID_NOT_SOLID ))
{
trace_t tr;
Vector vUpBit = GetAbsOrigin();
vUpBit.z += 5.0;
UTIL_TraceEntity( this, GetAbsOrigin(), vUpBit, MASK_SHOT, &tr );
if ( !tr.startsolid && (tr.fraction == 1.0) )
{
RemoveSolidFlags( FSOLID_NOT_SOLID );
}
}
trace_t tr;
// NOT MASK_SHOT because we want only simple hit boxes
UTIL_TraceLine( GetAbsOrigin(), m_vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
// ALERT( at_console, "%f : %f\n", tr.flFraction, m_flBeamLength );
// respawn detect.
if ( !m_pBeam )
{
MakeBeam( );
if ( tr.m_pEnt )
m_hOwner = tr.m_pEnt; // reset owner too
}
CBaseEntity *pEntity = tr.m_pEnt;
CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pEntity );
if (pBCC || fabs( m_flBeamLength - tr.fraction ) > 0.001)
{
m_iHealth = 0;
Event_Killed( CTakeDamageInfo( (CBaseEntity*)m_hOwner, this, 100, GIB_NORMAL ) );
return;
}
SetNextThink( gpGlobals->curtime + 0.1f );
}
int CTripmineGrenade::OnTakeDamage_Alive( const CTakeDamageInfo &info )
{
if (gpGlobals->curtime < m_flPowerUp && info.GetDamage() < m_iHealth)
{
// disable
// Create( "weapon_tripmine", GetLocalOrigin() + m_vecDir * 24, GetAngles() );
SetThink( SUB_Remove );
SetNextThink( gpGlobals->curtime + 0.1f );
KillBeam();
return FALSE;
}
return BaseClass::OnTakeDamage_Alive( info );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CTripmineGrenade::Event_Killed( const CTakeDamageInfo &info )
{
m_takedamage = DAMAGE_NO;
SetThink( DelayDeathThink );
SetNextThink( gpGlobals->curtime + 0.5 );
EmitSound( "TripmineGrenade.StopSound" );
}
void CTripmineGrenade::DelayDeathThink( void )
{
KillBeam();
trace_t tr;
UTIL_TraceLine ( GetAbsOrigin() + m_vecDir * 8, GetAbsOrigin() - m_vecDir * 64, MASK_SOLID, this, COLLISION_GROUP_NONE, & tr);
UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START );
Explode( &tr, DMG_BLAST );
}

View File

@ -1,55 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef GRENADE_TRIPMINE_H
#define GRENADE_TRIPMINE_H
#ifdef _WIN32
#pragma once
#endif
#include "basegrenade_shared.h"
class CBeam;
class CTripmineGrenade : public CBaseGrenade
{
public:
DECLARE_CLASS( CTripmineGrenade, CBaseGrenade );
CTripmineGrenade();
void Spawn( void );
void Precache( void );
int OnTakeDamage_Alive( const CTakeDamageInfo &info );
void WarningThink( void );
void PowerupThink( void );
void BeamBreakThink( void );
void DelayDeathThink( void );
void Event_Killed( const CTakeDamageInfo &info );
void MakeBeam( void );
void KillBeam( void );
public:
EHANDLE m_hOwner;
private:
float m_flPowerUp;
Vector m_vecDir;
Vector m_vecEnd;
float m_flBeamLength;
CBeam *m_pBeam;
Vector m_posOwner;
Vector m_angleOwner;
DECLARE_DATADESC();
};
#endif // GRENADE_TRIPMINE_H

View File

@ -56,7 +56,6 @@
#include "physobj.h"
#include "ai_network.h"
#include "ai_node.h"
#include "weapon_physcannon.h"
#include "saverestoretypes.h"
#include "saverestore.h"
#include "chaos.h"

View File

@ -5,22 +5,623 @@
//=============================================================================//
#include "cbase.h"
#include "basehlcombatweapon.h"
#include "basehlcombatweapon_shared.h"
#include "basegrenade_shared.h"
#include "player.h"
#include "gamerules.h"
#include "grenade_tripmine.h"
#include "grenade_satchel.h"
//#include "grenade_tripmine.h"
//#include "grenade_satchel.h"
#include "entitylist.h"
#include "weapon_slam.h"
#include "npcevent.h"
#include "in_buttons.h"
#include "soundenvelope.h"
#include "engine/IEngineSound.h"
#include "beam_shared.h"
#include "shake.h"
#include "vstdlib/random.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define SLAM_PRIMARY_VOLUME 450
ConVar sk_plr_dmg_satchel ( "sk_plr_dmg_satchel","0");
ConVar sk_npc_dmg_satchel("sk_npc_dmg_satchel", "0");
ConVar sk_satchel_radius("sk_satchel_radius", "0");
extern const char* g_pModelNameLaser;
ConVar sk_plr_dmg_tripmine("sk_plr_dmg_tripmine", "0");
ConVar sk_npc_dmg_tripmine("sk_npc_dmg_tripmine", "0");
ConVar sk_tripmine_radius("sk_tripmine_radius", "0");
LINK_ENTITY_TO_CLASS(npc_tripmine, CTripmineGrenade);
BEGIN_DATADESC(CTripmineGrenade)
DEFINE_FIELD(m_hOwner, FIELD_EHANDLE),
DEFINE_FIELD(m_flPowerUp, FIELD_TIME),
DEFINE_FIELD(m_vecDir, FIELD_VECTOR),
DEFINE_FIELD(m_vecEnd, FIELD_POSITION_VECTOR),
DEFINE_FIELD(m_flBeamLength, FIELD_FLOAT),
DEFINE_FIELD(m_pBeam, FIELD_CLASSPTR),
DEFINE_FIELD(m_posOwner, FIELD_POSITION_VECTOR),
DEFINE_FIELD(m_angleOwner, FIELD_VECTOR),
// Function Pointers
DEFINE_THINKFUNC(WarningThink),
DEFINE_THINKFUNC(PowerupThink),
DEFINE_THINKFUNC(BeamBreakThink),
DEFINE_THINKFUNC(DelayDeathThink),
END_DATADESC()
CTripmineGrenade::CTripmineGrenade()
{
m_vecDir.Init();
m_vecEnd.Init();
m_posOwner.Init();
m_angleOwner.Init();
}
void CTripmineGrenade::Spawn(void)
{
Precache();
// motor
SetMoveType(MOVETYPE_FLY);
SetSolid(SOLID_BBOX);
AddSolidFlags(FSOLID_NOT_SOLID);
SetModel("models/Weapons/w_slam.mdl");
//m_flCycle = 0;
SetCycle(0);
m_nBody = 3;
m_flDamage = sk_plr_dmg_tripmine.GetFloat();
m_DmgRadius = sk_tripmine_radius.GetFloat();
ResetSequenceInfo();
m_flPlaybackRate = 0;
UTIL_SetSize(this, Vector(-4, -4, -2), Vector(4, 4, 2));
m_flPowerUp = gpGlobals->curtime + 2.0;
SetThink(&CTripmineGrenade::PowerupThink);
SetNextThink(gpGlobals->curtime + 0.2);
m_takedamage = DAMAGE_YES;
m_iHealth = 1;
EmitSound("TripmineGrenade.Charge");
// Tripmine sits at 90 on wall so rotate back to get m_vecDir
QAngle angles = GetLocalAngles();
angles.x -= 90;
AngleVectors(angles, &m_vecDir);
m_vecEnd = GetLocalOrigin() + m_vecDir * 2048;
}
void CTripmineGrenade::Precache(void)
{
PrecacheModel("models/Weapons/w_slam.mdl");
PrecacheScriptSound("TripmineGrenade.Charge");
PrecacheScriptSound("TripmineGrenade.PowerUp");
PrecacheScriptSound("TripmineGrenade.StopSound");
PrecacheScriptSound("TripmineGrenade.Activate");
PrecacheScriptSound("TripmineGrenade.ShootRope");
PrecacheScriptSound("TripmineGrenade.Hook");
}
void CTripmineGrenade::WarningThink(void)
{
// set to power up
SetThink(&CTripmineGrenade::PowerupThink);
SetNextThink(gpGlobals->curtime + 1.0f);
}
void CTripmineGrenade::PowerupThink(void)
{
if (gpGlobals->curtime > m_flPowerUp)
{
MakeBeam();
RemoveSolidFlags(FSOLID_NOT_SOLID);
m_bIsLive = true;
// play enabled sound
EmitSound("TripmineGrenade.PowerUp");;
}
SetNextThink(gpGlobals->curtime + 0.1f);
}
void CTripmineGrenade::KillBeam(void)
{
if (m_pBeam)
{
UTIL_Remove(m_pBeam);
m_pBeam = NULL;
}
}
void CTripmineGrenade::MakeBeam(void)
{
trace_t tr;
UTIL_TraceLine(GetAbsOrigin(), m_vecEnd, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr);
m_flBeamLength = tr.fraction;
// If I hit a living thing, send the beam through me so it turns on briefly
// and then blows the living thing up
CBaseEntity *pEntity = tr.m_pEnt;
CBaseCombatCharacter *pBCC = ToBaseCombatCharacter(pEntity);
// Draw length is not the beam length if entity is in the way
float drawLength = tr.fraction;
if (pBCC)
{
SetOwnerEntity(pBCC);
UTIL_TraceLine(GetAbsOrigin(), m_vecEnd, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr);
m_flBeamLength = tr.fraction;
SetOwnerEntity(NULL);
}
// set to follow laser spot
SetThink(&CTripmineGrenade::BeamBreakThink);
// Delay first think slightly so beam has time
// to appear if person right in front of it
SetNextThink(gpGlobals->curtime + 1.0f);
Vector vecTmpEnd = GetLocalOrigin() + m_vecDir * 2048 * drawLength;
m_pBeam = CBeam::BeamCreate(g_pModelNameLaser, 1.0);
m_pBeam->PointEntInit(vecTmpEnd, this);
m_pBeam->SetColor(0, 214, 198);
m_pBeam->SetScrollRate(25.6);
m_pBeam->SetBrightness(64);
}
void CTripmineGrenade::BeamBreakThink(void)
{
// See if I can go solid yet (has dropper moved out of way?)
if (IsSolidFlagSet(FSOLID_NOT_SOLID))
{
trace_t tr;
Vector vUpBit = GetAbsOrigin();
vUpBit.z += 5.0;
UTIL_TraceEntity(this, GetAbsOrigin(), vUpBit, MASK_SHOT, &tr);
if (!tr.startsolid && (tr.fraction == 1.0))
{
RemoveSolidFlags(FSOLID_NOT_SOLID);
}
}
trace_t tr;
// NOT MASK_SHOT because we want only simple hit boxes
UTIL_TraceLine(GetAbsOrigin(), m_vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr);
// ALERT( at_console, "%f : %f\n", tr.flFraction, m_flBeamLength );
// respawn detect.
if (!m_pBeam)
{
MakeBeam();
if (tr.m_pEnt)
m_hOwner = tr.m_pEnt; // reset owner too
}
CBaseEntity *pEntity = tr.m_pEnt;
CBaseCombatCharacter *pBCC = ToBaseCombatCharacter(pEntity);
if (pBCC || fabs(m_flBeamLength - tr.fraction) > 0.001)
{
m_iHealth = 0;
Event_Killed(CTakeDamageInfo((CBaseEntity*)m_hOwner, this, 100, GIB_NORMAL));
return;
}
SetNextThink(gpGlobals->curtime + 0.1f);
}
int CTripmineGrenade::OnTakeDamage_Alive(const CTakeDamageInfo &info)
{
if (gpGlobals->curtime < m_flPowerUp && info.GetDamage() < m_iHealth)
{
// disable
// Create( "weapon_tripmine", GetLocalOrigin() + m_vecDir * 24, GetAngles() );
SetThink(&CTripmineGrenade::SUB_Remove);
SetNextThink(gpGlobals->curtime + 0.1f);
KillBeam();
//return false;
}
return false;// BaseClass::OnTakeDamage_Alive(info);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CTripmineGrenade::Event_Killed(const CTakeDamageInfo &info)
{
m_takedamage = DAMAGE_NO;
SetThink(&CTripmineGrenade::DelayDeathThink);
SetNextThink(gpGlobals->curtime + 0.5);
EmitSound("TripmineGrenade.StopSound");
}
void CTripmineGrenade::DelayDeathThink(void)
{
KillBeam();
trace_t tr;
UTIL_TraceLine(GetAbsOrigin() + m_vecDir * 8, GetAbsOrigin() - m_vecDir * 64, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr);
UTIL_ScreenShake(GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START);
Explode(&tr, DMG_BLAST);
}
BEGIN_DATADESC(CSatchelCharge)
DEFINE_SOUNDPATCH(m_soundSlide),
DEFINE_FIELD(m_flSlideVolume, FIELD_FLOAT),
DEFINE_FIELD(m_flNextBounceSoundTime, FIELD_TIME),
DEFINE_FIELD(m_bInAir, FIELD_BOOLEAN),
DEFINE_FIELD(m_vLastPosition, FIELD_POSITION_VECTOR),
DEFINE_FIELD(m_pMyWeaponSLAM, FIELD_CLASSPTR),
DEFINE_FIELD(m_bIsAttached, FIELD_BOOLEAN),
// Function Pointers
DEFINE_ENTITYFUNC(SatchelTouch),
DEFINE_THINKFUNC(SatchelThink),
DEFINE_USEFUNC(SatchelUse),
END_DATADESC()
LINK_ENTITY_TO_CLASS(npc_satchel, CSatchelCharge);
//=========================================================
// Deactivate - do whatever it is we do to an orphaned
// satchel when we don't want it in the world anymore.
//=========================================================
void CSatchelCharge::Deactivate(void)
{
AddSolidFlags(FSOLID_NOT_SOLID);
UTIL_Remove(this);
}
void CSatchelCharge::Spawn(void)
{
Precache();
// motor
SetMoveType(MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE);
SetSolid(SOLID_BBOX);
SetCollisionGroup(COLLISION_GROUP_PROJECTILE);
SetModel("models/Weapons/w_slam.mdl");
UTIL_SetSize(this, Vector(-6, -6, -2), Vector(6, 6, 2));
SetTouch(&CSatchelCharge::SatchelTouch);
SetUse(&CSatchelCharge::SatchelUse);
SetThink(&CSatchelCharge::SatchelThink);
SetNextThink(gpGlobals->curtime + 0.1f);
m_flDamage = sk_plr_dmg_satchel.GetFloat();
m_DmgRadius = sk_satchel_radius.GetFloat();
m_takedamage = DAMAGE_YES;
m_iHealth = 1;
SetGravity(UTIL_ScaleForGravity(560)); // slightly lower gravity
SetFriction(1.0);
SetSequence(1);
m_bIsAttached = false;
m_bInAir = true;
m_flSlideVolume = -1.0;
m_flNextBounceSoundTime = 0;
m_vLastPosition = vec3_origin;
InitSlideSound();
}
//-----------------------------------------------------------------------------
void CSatchelCharge::InitSlideSound(void)
{
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
CPASAttenuationFilter filter(this);
m_soundSlide = controller.SoundCreate(filter, entindex(), CHAN_STATIC, "SatchelCharge.Slide", ATTN_NORM);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CSatchelCharge::KillSlideSound(void)
{
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
controller.CommandClear(m_soundSlide);
controller.SoundFadeOut(m_soundSlide, 0.0);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CSatchelCharge::SatchelUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{
KillSlideSound();
SetThink(&CSatchelCharge::Detonate);
SetNextThink(gpGlobals->curtime);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CSatchelCharge::SatchelTouch(CBaseEntity *pOther)
{
Assert(pOther);
if (!pOther->IsSolid())
return;
// If successfully thrown and touching the
// NPC that released this grenade, pick it up
if (pOther == GetThrower() && GetOwnerEntity() == NULL)
{
CBasePlayer *pPlayer = ToBasePlayer(m_pMyWeaponSLAM->GetOwner());
if (pPlayer)
{
// Give the player ammo
pPlayer->GiveAmmo(1, m_pMyWeaponSLAM->m_iSecondaryAmmoType);
CPASAttenuationFilter filter(pPlayer, "SatchelCharge.Pickup");
EmitSound(filter, pPlayer->entindex(), "SatchelCharge.Pickup");
m_bIsLive = false;
// Take weapon out of detonate mode if necessary
if (!m_pMyWeaponSLAM->AnyUndetonatedCharges())
{
m_pMyWeaponSLAM->m_bDetonatorArmed = false;
m_pMyWeaponSLAM->m_bNeedDetonatorHolster = true;
// Put detonator away right away
m_pMyWeaponSLAM->SetWeaponIdleTime(gpGlobals->curtime);
}
// Kill any sliding sound
KillSlideSound();
// Remove satchel charge from world
UTIL_Remove(this);
return;
}
}
StudioFrameAdvance();
// Is it attached to a wall?
if (m_bIsAttached)
{
return;
}
SetGravity(1);// normal gravity now
// HACKHACK - On ground isn't always set, so look for ground underneath
trace_t tr;
UTIL_TraceLine(GetAbsOrigin(), GetAbsOrigin() - Vector(0, 0, 10), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);
if (tr.fraction < 1.0)
{
// add a bit of static friction
SetAbsVelocity(GetAbsVelocity() * 0.85);
SetLocalAngularVelocity(GetLocalAngularVelocity() * 0.8);
}
UpdateSlideSound();
if (m_bInAir)
{
BounceSound();
m_bInAir = false;
}
}
void CSatchelCharge::UpdateSlideSound(void)
{
if (!m_soundSlide)
{
return;
}
float volume = GetAbsVelocity().Length2D() / 1000;
if (volume < 0.01 && m_soundSlide)
{
KillSlideSound();
return;
}
// HACKHACK - On ground isn't always set, so look for ground underneath
trace_t tr;
UTIL_TraceLine(GetAbsOrigin(), GetAbsOrigin() - Vector(0, 0, 10), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
if (tr.fraction < 1.0)
{
if (m_flSlideVolume == -1.0)
{
controller.CommandClear(m_soundSlide);
controller.Play(m_soundSlide, 1.0, 100);
m_flSlideVolume = 1.0;
}
else
{
float volume = GetAbsVelocity().Length() / 1000;
if (volume < m_flSlideVolume)
{
m_flSlideVolume = volume;
controller.CommandClear(m_soundSlide);
controller.SoundChangeVolume(m_soundSlide, volume, 0.1);
}
}
}
else
{
controller.CommandClear(m_soundSlide);
controller.SoundChangeVolume(m_soundSlide, 0.0, 0.01);
m_flSlideVolume = -1.0;
m_bInAir = true;
return;
}
}
void CSatchelCharge::SatchelThink(void)
{
// If attached resize so player can pick up off wall
if (m_bIsAttached)
{
UTIL_SetSize(this, Vector(-2, -2, -6), Vector(2, 2, 6));
}
UpdateSlideSound();
// See if I can lose my owner (has dropper moved out of way?)
// Want do this so owner can shoot the satchel charge
if (GetOwnerEntity())
{
trace_t tr;
Vector vUpABit = GetAbsOrigin();
vUpABit.z += 5.0;
CBaseEntity* saveOwner = GetOwnerEntity();
SetOwnerEntity(NULL);
UTIL_TraceEntity(this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr);
if (tr.startsolid || tr.fraction != 1.0)
{
SetOwnerEntity(saveOwner);
}
}
// Bounce movement code gets this think stuck occasionally so check if I've
// succeeded in moving, otherwise kill my motions.
else if ((GetAbsOrigin() - m_vLastPosition).LengthSqr()<1)
{
SetAbsVelocity(vec3_origin);
QAngle angVel = GetLocalAngularVelocity();
angVel.y = 0;
SetLocalAngularVelocity(angVel);
// Kill any remaining sound
KillSlideSound();
// Clear think function
SetThink(NULL);
return;
}
m_vLastPosition = GetAbsOrigin();
StudioFrameAdvance();
SetNextThink(gpGlobals->curtime + 0.1f);
if (!IsInWorld())
{
// Kill any remaining sound
KillSlideSound();
UTIL_Remove(this);
return;
}
// Is it attached to a wall?
if (m_bIsAttached)
{
return;
}
Vector vecNewVel = GetAbsVelocity();
if (GetWaterLevel() == 3)
{
SetMoveType(MOVETYPE_FLY);
vecNewVel *= 0.8;
vecNewVel.z += 8;
SetLocalAngularVelocity(GetLocalAngularVelocity() * 0.9);
}
else if (GetWaterLevel() == 0)
{
SetMoveType(MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE);
}
else
{
vecNewVel.z -= 8;
}
SetAbsVelocity(vecNewVel);
}
void CSatchelCharge::Precache(void)
{
PrecacheModel("models/Weapons/w_slam.mdl");
PrecacheScriptSound("SatchelCharge.Pickup");
PrecacheScriptSound("SatchelCharge.Bounce");
PrecacheScriptSound("SatchelCharge.Slide");
}
void CSatchelCharge::BounceSound(void)
{
if (gpGlobals->curtime > m_flNextBounceSoundTime)
{
EmitSound("SatchelCharge.Bounce");
m_flNextBounceSoundTime = gpGlobals->curtime + 0.1;
}
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input :
// Output :
//-----------------------------------------------------------------------------
CSatchelCharge::CSatchelCharge(void)
{
m_vLastPosition.Init();
m_pMyWeaponSLAM = NULL;
}
CSatchelCharge::~CSatchelCharge(void)
{
CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController();
controller.SoundDestroy(m_soundSlide);
}
BEGIN_DATADESC( CWeapon_SLAM )
DEFINE_FIELD( m_tSlamState, FIELD_INTEGER ),
@ -35,8 +636,8 @@ BEGIN_DATADESC( CWeapon_SLAM )
DEFINE_FIELD( m_flWallSwitchTime, FIELD_TIME ),
// Function Pointers
DEFINE_FUNCTION( SLAMThink ),
DEFINE_FUNCTION( SlamTouch ),
DEFINE_THINKFUNC(SLAMThink),
DEFINE_USEFUNC(SlamTouch),
END_DATADESC()
@ -97,7 +698,7 @@ void CWeapon_SLAM::Precache( void )
//------------------------------------------------------------------------------
void CWeapon_SLAM::SetPickupTouch( void )
{
SetTouch(SlamTouch);
SetTouch(&CWeapon_SLAM::SlamTouch);
}
//-----------------------------------------------------------------------------
@ -934,7 +1535,7 @@ bool CWeapon_SLAM::Deploy( void )
m_bDetonatorArmed = AnyUndetonatedCharges();
SetThink( SLAMThink );
SetThink(&CWeapon_SLAM::SLAMThink);
SetNextThink( gpGlobals->curtime + 0.1f );
SetModel( GetViewModel() );

View File

@ -11,12 +11,13 @@
// $NoKeywords: $
//=============================================================================//
#ifndef WEAPONSLAM_H
#define WEAPONSLAM_H
#ifndef HL2MP
//i don't know why but this has to be changed to 2.
#ifndef WEAPONSLAM2_H
#define WEAPONSLAM2_H
#pragma once
#include "basegrenade_shared.h"
#include "basehlcombatweapon.h"
#include "basehlcombatweapon_shared.h"
class CSoundPatch;//
enum SlamState_t
{
@ -25,10 +26,12 @@ enum SlamState_t
SLAM_SATCHEL_ATTACH,
};
class CBeam;
class CWeapon_SLAM : public CBaseHLCombatWeapon
{
public:
DECLARE_CLASS( CWeapon_SLAM, CBaseHLCombatWeapon );
DECLARE_CLASS(CWeapon_SLAM, CBaseHLCombatWeapon);
DECLARE_SERVERCLASS();
@ -43,34 +46,34 @@ public:
bool m_bAttachTripmine;
float m_flWallSwitchTime;
void Spawn( void );
void Precache( void );
void Spawn(void);
void Precache(void);
int CapabilitiesGet( void ) { return bits_CAP_WEAPON_RANGE_ATTACK1; }
void PrimaryAttack( void );
void SecondaryAttack( void );
void WeaponIdle( void );
void WeaponSwitch( void );
void SLAMThink( void );
int CapabilitiesGet(void) { return bits_CAP_WEAPON_RANGE_ATTACK1; }
void PrimaryAttack(void);
void SecondaryAttack(void);
void WeaponIdle(void);
void WeaponSwitch(void);
void SLAMThink(void);
void SetPickupTouch( void );
void SlamTouch( CBaseEntity *pOther ); // default weapon touch
void ItemPostFrame( void );
bool Reload( void );
void SetSlamState( SlamState_t newState );
void SetPickupTouch(void);
void SlamTouch(CBaseEntity *pOther); // default weapon touch
void ItemPostFrame(void);
bool Reload(void);
void SetSlamState(SlamState_t newState);
bool CanAttachSLAM(void); // In position where can attach SLAM?
bool AnyUndetonatedCharges(void);
void StartTripmineAttach( void );
void TripmineAttach( void );
void StartTripmineAttach(void);
void TripmineAttach(void);
void StartSatchelDetonate( void );
void SatchelDetonate( void );
void StartSatchelThrow( void );
void StartSatchelAttach( void );
void SatchelThrow( void );
void SatchelAttach( void );
bool Deploy( void );
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
void StartSatchelDetonate(void);
void SatchelDetonate(void);
void StartSatchelThrow(void);
void StartSatchelAttach(void);
void SatchelThrow(void);
void SatchelAttach(void);
bool Deploy(void);
bool Holster(CBaseCombatWeapon *pSwitchingTo = NULL);
CWeapon_SLAM();
@ -79,5 +82,71 @@ public:
DECLARE_DATADESC();
};
#endif //HL2MP
#endif //WEAPONSLAM_H
class CSatchelCharge : public CBaseGrenade
{
public:
DECLARE_CLASS(CSatchelCharge, CBaseGrenade);
void Spawn(void);
void Precache(void);
void BounceSound(void);
void UpdateSlideSound(void);
void KillSlideSound(void);
void SatchelTouch(CBaseEntity *pOther);
void SatchelThink(void);
void SatchelUse(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
CSoundPatch* m_soundSlide;
float m_flSlideVolume;
float m_flNextBounceSoundTime;
bool m_bInAir;
Vector m_vLastPosition;
public:
CWeapon_SLAM* m_pMyWeaponSLAM; // Who shot me..
bool m_bIsAttached;
void Deactivate(void);
CSatchelCharge();
~CSatchelCharge();
DECLARE_DATADESC();
private:
void InitSlideSound(void);
};
class CTripmineGrenade : public CBaseGrenade
{
public:
DECLARE_CLASS(CTripmineGrenade, CBaseGrenade);
CTripmineGrenade();
void Spawn(void);
void Precache(void);
int OnTakeDamage_Alive(const CTakeDamageInfo &info);
void WarningThink(void);
void PowerupThink(void);
void BeamBreakThink(void);
void DelayDeathThink(void);
void Event_Killed(const CTakeDamageInfo &info);
void MakeBeam(void);
void KillBeam(void);
EHANDLE m_hOwner;
float m_flPowerUp;
Vector m_vecDir;
Vector m_vecEnd;
float m_flBeamLength;
CBeam *m_pBeam;
Vector m_posOwner;
Vector m_angleOwner;
DECLARE_DATADESC();
};
#endif //WEAPONSLAM2_H

View File

@ -1,217 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "player.h"
#include "soundenvelope.h"
#include "engine/IEngineSound.h"
#include "explode.h"
#include "Sprite.h"
#include "grenade_satchel.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define SLAM_SPRITE "sprites/redglow1.vmt"
ConVar sk_plr_dmg_satchel ( "sk_plr_dmg_satchel","0");
ConVar sk_npc_dmg_satchel ( "sk_npc_dmg_satchel","0");
ConVar sk_satchel_radius ( "sk_satchel_radius","0");
BEGIN_DATADESC( CSatchelCharge )
DEFINE_FIELD( m_flNextBounceSoundTime, FIELD_TIME ),
DEFINE_FIELD( m_bInAir, FIELD_BOOLEAN ),
DEFINE_FIELD( m_vLastPosition, FIELD_POSITION_VECTOR ),
DEFINE_FIELD( m_pMyWeaponSLAM, FIELD_CLASSPTR ),
DEFINE_FIELD( m_bIsAttached, FIELD_BOOLEAN ),
// Function Pointers
DEFINE_THINKFUNC( SatchelThink ),
// Inputs
DEFINE_INPUTFUNC( FIELD_VOID, "Explode", InputExplode),
END_DATADESC()
LINK_ENTITY_TO_CLASS( npc_satchel, CSatchelCharge );
//=========================================================
// Deactivate - do whatever it is we do to an orphaned
// satchel when we don't want it in the world anymore.
//=========================================================
void CSatchelCharge::Deactivate( void )
{
AddSolidFlags( FSOLID_NOT_SOLID );
UTIL_Remove( this );
if ( m_hGlowSprite != NULL )
{
UTIL_Remove( m_hGlowSprite );
m_hGlowSprite = NULL;
}
}
void CSatchelCharge::Spawn( void )
{
Precache( );
SetModel( "models/Weapons/w_slam.mdl" );
VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false );
SetMoveType( MOVETYPE_VPHYSICS );
SetCollisionGroup( COLLISION_GROUP_WEAPON );
UTIL_SetSize(this, Vector( -6, -6, -2), Vector(6, 6, 2));
SetThink( &CSatchelCharge::SatchelThink );
SetNextThink( gpGlobals->curtime + 0.1f );
m_flDamage = sk_plr_dmg_satchel.GetFloat();
m_DmgRadius = sk_satchel_radius.GetFloat();
m_takedamage = DAMAGE_YES;
m_iHealth = 1;
SetGravity( UTIL_ScaleForGravity( 560 ) ); // slightly lower gravity
SetFriction( 1.0 );
SetSequence( 1 );
SetDamage( 150 );
m_bIsAttached = false;
m_bInAir = true;
m_flNextBounceSoundTime = 0;
m_vLastPosition = vec3_origin;
m_hGlowSprite = NULL;
CreateEffects();
}
//-----------------------------------------------------------------------------
// Purpose: Start up any effects for us
//-----------------------------------------------------------------------------
void CSatchelCharge::CreateEffects( void )
{
// Only do this once
if ( m_hGlowSprite != NULL )
return;
// Create a blinking light to show we're an active SLAM
m_hGlowSprite = CSprite::SpriteCreate( SLAM_SPRITE, GetAbsOrigin(), false );
m_hGlowSprite->SetAttachment( this, 0 );
m_hGlowSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxStrobeFast );
m_hGlowSprite->SetBrightness( 255, 1.0f );
m_hGlowSprite->SetScale( 0.2f, 0.5f );
m_hGlowSprite->TurnOn();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CSatchelCharge::InputExplode( inputdata_t &inputdata )
{
ExplosionCreate( GetAbsOrigin() + Vector( 0, 0, 16 ), GetAbsAngles(), GetThrower(), GetDamage(), 200,
SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE, 0.0f, this);
UTIL_Remove( this );
}
void CSatchelCharge::SatchelThink( void )
{
// If attached resize so player can pick up off wall
if (m_bIsAttached)
{
UTIL_SetSize(this, Vector( -2, -2, -6), Vector(2, 2, 6));
}
// See if I can lose my owner (has dropper moved out of way?)
// Want do this so owner can shoot the satchel charge
if (GetOwnerEntity())
{
trace_t tr;
Vector vUpABit = GetAbsOrigin();
vUpABit.z += 5.0;
CBaseEntity* saveOwner = GetOwnerEntity();
SetOwnerEntity( NULL );
UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr );
if ( tr.startsolid || tr.fraction != 1.0 )
{
SetOwnerEntity( saveOwner );
}
}
// Bounce movement code gets this think stuck occasionally so check if I've
// succeeded in moving, otherwise kill my motions.
else if ((GetAbsOrigin() - m_vLastPosition).LengthSqr()<1)
{
SetAbsVelocity( vec3_origin );
QAngle angVel = GetLocalAngularVelocity();
angVel.y = 0;
SetLocalAngularVelocity( angVel );
// Clear think function
SetThink(NULL);
return;
}
m_vLastPosition= GetAbsOrigin();
StudioFrameAdvance( );
SetNextThink( gpGlobals->curtime + 0.1f );
if (!IsInWorld())
{
UTIL_Remove( this );
return;
}
// Is it attached to a wall?
if (m_bIsAttached)
{
return;
}
}
void CSatchelCharge::Precache( void )
{
PrecacheModel("models/Weapons/w_slam.mdl");
PrecacheModel(SLAM_SPRITE);
}
void CSatchelCharge::BounceSound( void )
{
if (gpGlobals->curtime > m_flNextBounceSoundTime)
{
m_flNextBounceSoundTime = gpGlobals->curtime + 0.1;
}
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input :
// Output :
//-----------------------------------------------------------------------------
CSatchelCharge::CSatchelCharge(void)
{
m_vLastPosition.Init();
m_pMyWeaponSLAM = NULL;
}
CSatchelCharge::~CSatchelCharge(void)
{
if ( m_hGlowSprite != NULL )
{
UTIL_Remove( m_hGlowSprite );
m_hGlowSprite = NULL;
}
}

View File

@ -1,56 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Satchel Charge
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#ifndef SATCHEL_H
#define SATCHEL_H
#ifdef _WIN32
#pragma once
#endif
#include "basegrenade_shared.h"
#include "hl2mp/weapon_slam.h"
class CSoundPatch;
class CSprite;
class CSatchelCharge : public CBaseGrenade
{
public:
DECLARE_CLASS( CSatchelCharge, CBaseGrenade );
void Spawn( void );
void Precache( void );
void BounceSound( void );
void SatchelTouch( CBaseEntity *pOther );
void SatchelThink( void );
// Input handlers
void InputExplode( inputdata_t &inputdata );
float m_flNextBounceSoundTime;
bool m_bInAir;
Vector m_vLastPosition;
public:
CWeapon_SLAM* m_pMyWeaponSLAM; // Who shot me..
bool m_bIsAttached;
void Deactivate( void );
CSatchelCharge();
~CSatchelCharge();
DECLARE_DATADESC();
private:
void CreateEffects( void );
CHandle<CSprite> m_hGlowSprite;
};
#endif //SATCHEL_H

View File

@ -1,276 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Implements the tripmine grenade.
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "beam_shared.h"
#include "shake.h"
#include "grenade_tripmine.h"
#include "vstdlib/random.h"
#include "engine/IEngineSound.h"
#include "explode.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
extern const char* g_pModelNameLaser;
ConVar sk_plr_dmg_tripmine ( "sk_plr_dmg_tripmine","0");
ConVar sk_npc_dmg_tripmine ( "sk_npc_dmg_tripmine","0");
ConVar sk_tripmine_radius ( "sk_tripmine_radius","0");
LINK_ENTITY_TO_CLASS( npc_tripmine, CTripmineGrenade );
BEGIN_DATADESC( CTripmineGrenade )
DEFINE_FIELD( m_hOwner, FIELD_EHANDLE ),
DEFINE_FIELD( m_flPowerUp, FIELD_TIME ),
DEFINE_FIELD( m_vecDir, FIELD_VECTOR ),
DEFINE_FIELD( m_vecEnd, FIELD_POSITION_VECTOR ),
DEFINE_FIELD( m_flBeamLength, FIELD_FLOAT ),
DEFINE_FIELD( m_pBeam, FIELD_CLASSPTR ),
DEFINE_FIELD( m_posOwner, FIELD_POSITION_VECTOR ),
DEFINE_FIELD( m_angleOwner, FIELD_VECTOR ),
// Function Pointers
DEFINE_THINKFUNC( WarningThink ),
DEFINE_THINKFUNC( PowerupThink ),
DEFINE_THINKFUNC( BeamBreakThink ),
DEFINE_THINKFUNC( DelayDeathThink ),
END_DATADESC()
CTripmineGrenade::CTripmineGrenade()
{
m_vecDir.Init();
m_vecEnd.Init();
m_posOwner.Init();
m_angleOwner.Init();
}
void CTripmineGrenade::Spawn( void )
{
Precache( );
// motor
SetMoveType( MOVETYPE_FLY );
SetSolid( SOLID_BBOX );
SetModel( "models/Weapons/w_slam.mdl" );
IPhysicsObject *pObject = VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, true );
pObject->EnableMotion( false );
SetCollisionGroup( COLLISION_GROUP_WEAPON );
SetCycle( 0.0f );
m_nBody = 3;
m_flDamage = sk_plr_dmg_tripmine.GetFloat();
m_DmgRadius = sk_tripmine_radius.GetFloat();
ResetSequenceInfo( );
m_flPlaybackRate = 0;
UTIL_SetSize(this, Vector( -4, -4, -2), Vector(4, 4, 2));
m_flPowerUp = gpGlobals->curtime + 2.0;
SetThink( &CTripmineGrenade::PowerupThink );
SetNextThink( gpGlobals->curtime + 0.2 );
m_takedamage = DAMAGE_YES;
m_iHealth = 1;
EmitSound( "TripmineGrenade.Place" );
SetDamage ( 200 );
// Tripmine sits at 90 on wall so rotate back to get m_vecDir
QAngle angles = GetAbsAngles();
angles.x -= 90;
AngleVectors( angles, &m_vecDir );
m_vecEnd = GetAbsOrigin() + m_vecDir * 2048;
AddEffects( EF_NOSHADOW );
}
void CTripmineGrenade::Precache( void )
{
PrecacheModel("models/Weapons/w_slam.mdl");
PrecacheScriptSound( "TripmineGrenade.Place" );
PrecacheScriptSound( "TripmineGrenade.Activate" );
}
void CTripmineGrenade::WarningThink( void )
{
// set to power up
SetThink( &CTripmineGrenade::PowerupThink );
SetNextThink( gpGlobals->curtime + 1.0f );
}
void CTripmineGrenade::PowerupThink( void )
{
if (gpGlobals->curtime > m_flPowerUp)
{
MakeBeam( );
RemoveSolidFlags( FSOLID_NOT_SOLID );
m_bIsLive = true;
// play enabled sound
EmitSound( "TripmineGrenade.Activate" );
}
SetNextThink( gpGlobals->curtime + 0.1f );
}
void CTripmineGrenade::KillBeam( void )
{
if ( m_pBeam )
{
UTIL_Remove( m_pBeam );
m_pBeam = NULL;
}
}
void CTripmineGrenade::MakeBeam( void )
{
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), m_vecEnd, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
m_flBeamLength = tr.fraction;
// If I hit a living thing, send the beam through me so it turns on briefly
// and then blows the living thing up
CBaseEntity *pEntity = tr.m_pEnt;
CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pEntity );
// Draw length is not the beam length if entity is in the way
float drawLength = tr.fraction;
if (pBCC)
{
SetOwnerEntity( pBCC );
UTIL_TraceLine( GetAbsOrigin(), m_vecEnd, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
m_flBeamLength = tr.fraction;
SetOwnerEntity( NULL );
}
// set to follow laser spot
SetThink( &CTripmineGrenade::BeamBreakThink );
// Delay first think slightly so beam has time
// to appear if person right in front of it
SetNextThink( gpGlobals->curtime + 1.0f );
Vector vecTmpEnd = GetLocalOrigin() + m_vecDir * 2048 * drawLength;
m_pBeam = CBeam::BeamCreate( g_pModelNameLaser, 0.35 );
m_pBeam->PointEntInit( vecTmpEnd, this );
m_pBeam->SetColor( 255, 55, 52 );
m_pBeam->SetScrollRate( 25.6 );
m_pBeam->SetBrightness( 64 );
int beamAttach = LookupAttachment("beam_attach");
m_pBeam->SetEndAttachment( beamAttach );
}
void CTripmineGrenade::BeamBreakThink( void )
{
// See if I can go solid yet (has dropper moved out of way?)
if (IsSolidFlagSet( FSOLID_NOT_SOLID ))
{
trace_t tr;
Vector vUpBit = GetAbsOrigin();
vUpBit.z += 5.0;
UTIL_TraceEntity( this, GetAbsOrigin(), vUpBit, MASK_SHOT, &tr );
if ( !tr.startsolid && (tr.fraction == 1.0) )
{
RemoveSolidFlags( FSOLID_NOT_SOLID );
}
}
trace_t tr;
// NOT MASK_SHOT because we want only simple hit boxes
UTIL_TraceLine( GetAbsOrigin(), m_vecEnd, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
// ALERT( at_console, "%f : %f\n", tr.flFraction, m_flBeamLength );
// respawn detect.
if ( !m_pBeam )
{
MakeBeam( );
if ( tr.m_pEnt )
m_hOwner = tr.m_pEnt; // reset owner too
}
CBaseEntity *pEntity = tr.m_pEnt;
CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pEntity );
if (pBCC || fabs( m_flBeamLength - tr.fraction ) > 0.001)
{
m_iHealth = 0;
Event_Killed( CTakeDamageInfo( (CBaseEntity*)m_hOwner, this, 100, GIB_NORMAL ) );
return;
}
SetNextThink( gpGlobals->curtime + 0.05f );
}
#if 0 // FIXME: OnTakeDamage_Alive() is no longer called now that base grenade derives from CBaseAnimating
int CTripmineGrenade::OnTakeDamage_Alive( const CTakeDamageInfo &info )
{
if (gpGlobals->curtime < m_flPowerUp && info.GetDamage() < m_iHealth)
{
// disable
// Create( "weapon_tripmine", GetLocalOrigin() + m_vecDir * 24, GetAngles() );
SetThink( &CTripmineGrenade::SUB_Remove );
SetNextThink( gpGlobals->curtime + 0.1f );
KillBeam();
return FALSE;
}
return BaseClass::OnTakeDamage_Alive( info );
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
// Input :
// Output :
//-----------------------------------------------------------------------------
void CTripmineGrenade::Event_Killed( const CTakeDamageInfo &info )
{
m_takedamage = DAMAGE_NO;
SetThink( &CTripmineGrenade::DelayDeathThink );
SetNextThink( gpGlobals->curtime + 0.25 );
EmitSound( "TripmineGrenade.StopSound" );
}
void CTripmineGrenade::DelayDeathThink( void )
{
KillBeam();
trace_t tr;
UTIL_TraceLine ( GetAbsOrigin() + m_vecDir * 8, GetAbsOrigin() - m_vecDir * 64, MASK_SOLID, this, COLLISION_GROUP_NONE, & tr);
UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START );
ExplosionCreate( GetAbsOrigin() + m_vecDir * 8, GetAbsAngles(), m_hOwner, GetDamage(), 200,
SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE, 0.0f, this);
UTIL_Remove( this );
}

View File

@ -1,56 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef GRENADE_TRIPMINE_H
#define GRENADE_TRIPMINE_H
#ifdef _WIN32
#pragma once
#endif
#include "basegrenade_shared.h"
class CBeam;
class CTripmineGrenade : public CBaseGrenade
{
public:
DECLARE_CLASS( CTripmineGrenade, CBaseGrenade );
CTripmineGrenade();
void Spawn( void );
void Precache( void );
#if 0 // FIXME: OnTakeDamage_Alive() is no longer called now that base grenade derives from CBaseAnimating
int OnTakeDamage_Alive( const CTakeDamageInfo &info );
#endif
void WarningThink( void );
void PowerupThink( void );
void BeamBreakThink( void );
void DelayDeathThink( void );
void Event_Killed( const CTakeDamageInfo &info );
void MakeBeam( void );
void KillBeam( void );
public:
EHANDLE m_hOwner;
private:
float m_flPowerUp;
Vector m_vecDir;
Vector m_vecEnd;
float m_flBeamLength;
CBeam *m_pBeam;
Vector m_posOwner;
Vector m_angleOwner;
DECLARE_DATADESC();
};
#endif // GRENADE_TRIPMINE_H

View File

@ -1,435 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Basic BOT handling.
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "player.h"
#include "hl2mp_player.h"
#include "in_buttons.h"
#include "movehelper_server.h"
void ClientPutInServer( edict_t *pEdict, const char *playername );
void Bot_Think( CHL2MP_Player *pBot );
#ifdef DEBUG
ConVar bot_forcefireweapon( "bot_forcefireweapon", "", 0, "Force bots with the specified weapon to fire." );
ConVar bot_forceattack2( "bot_forceattack2", "0", 0, "When firing, use attack2." );
ConVar bot_forceattackon( "bot_forceattackon", "0", 0, "When firing, don't tap fire, hold it down." );
ConVar bot_flipout( "bot_flipout", "0", 0, "When on, all bots fire their guns." );
ConVar bot_defend( "bot_defend", "0", 0, "Set to a team number, and that team will all keep their combat shields raised." );
ConVar bot_changeclass( "bot_changeclass", "0", 0, "Force all bots to change to the specified class." );
ConVar bot_zombie( "bot_zombie", "0", 0, "Brraaaaaiiiins." );
static ConVar bot_mimic_yaw_offset( "bot_mimic_yaw_offset", "0", 0, "Offsets the bot yaw." );
ConVar bot_attack( "bot_attack", "1", 0, "Shoot!" );
ConVar bot_sendcmd( "bot_sendcmd", "", 0, "Forces bots to send the specified command." );
ConVar bot_crouch( "bot_crouch", "0", 0, "Bot crouches" );
#ifdef NEXT_BOT
extern ConVar bot_mimic;
#else
ConVar bot_mimic( "bot_mimic", "0", 0, "Bot uses usercmd of player by index." );
#endif
static int BotNumber = 1;
static int g_iNextBotTeam = -1;
static int g_iNextBotClass = -1;
typedef struct
{
bool backwards;
float nextturntime;
bool lastturntoright;
float nextstrafetime;
float sidemove;
QAngle forwardAngle;
QAngle lastAngles;
float m_flJoinTeamTime;
int m_WantedTeam;
int m_WantedClass;
} botdata_t;
static botdata_t g_BotData[ MAX_PLAYERS ];
//-----------------------------------------------------------------------------
// Purpose: Create a new Bot and put it in the game.
// Output : Pointer to the new Bot, or NULL if there's no free clients.
//-----------------------------------------------------------------------------
CBasePlayer *BotPutInServer( bool bFrozen, int iTeam )
{
g_iNextBotTeam = iTeam;
char botname[ 64 ];
Q_snprintf( botname, sizeof( botname ), "Bot%02i", BotNumber );
// This is an evil hack, but we use it to prevent sv_autojointeam from kicking in.
edict_t *pEdict = engine->CreateFakeClient( botname );
if (!pEdict)
{
Msg( "Failed to create Bot.\n");
return NULL;
}
// Allocate a CBasePlayer for the bot, and call spawn
//ClientPutInServer( pEdict, botname );
CHL2MP_Player *pPlayer = ((CHL2MP_Player *)CBaseEntity::Instance( pEdict ));
pPlayer->ClearFlags();
pPlayer->AddFlag( FL_CLIENT | FL_FAKECLIENT );
if ( bFrozen )
pPlayer->AddEFlags( EFL_BOT_FROZEN );
BotNumber++;
g_BotData[pPlayer->entindex()-1].m_WantedTeam = iTeam;
g_BotData[pPlayer->entindex()-1].m_flJoinTeamTime = gpGlobals->curtime + 0.3;
return pPlayer;
}
//-----------------------------------------------------------------------------
// Purpose: Run through all the Bots in the game and let them think.
//-----------------------------------------------------------------------------
void Bot_RunAll( void )
{
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CHL2MP_Player *pPlayer = ToHL2MPPlayer( UTIL_PlayerByIndex( i ) );
if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) )
{
Bot_Think( pPlayer );
}
}
}
bool RunMimicCommand( CUserCmd& cmd )
{
if ( bot_mimic.GetInt() <= 0 )
return false;
if ( bot_mimic.GetInt() > gpGlobals->maxClients )
return false;
CBasePlayer *pPlayer = UTIL_PlayerByIndex( bot_mimic.GetInt() );
if ( !pPlayer )
return false;
if ( !pPlayer->GetLastUserCommand() )
return false;
cmd = *pPlayer->GetLastUserCommand();
cmd.viewangles[YAW] += bot_mimic_yaw_offset.GetFloat();
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Simulates a single frame of movement for a player
// Input : *fakeclient -
// *viewangles -
// forwardmove -
// sidemove -
// upmove -
// buttons -
// impulse -
// msec -
// Output : virtual void
//-----------------------------------------------------------------------------
static void RunPlayerMove( CHL2MP_Player *fakeclient, const QAngle& viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, float frametime )
{
if ( !fakeclient )
return;
CUserCmd cmd;
// Store off the globals.. they're gonna get whacked
float flOldFrametime = gpGlobals->frametime;
float flOldCurtime = gpGlobals->curtime;
float flTimeBase = gpGlobals->curtime + gpGlobals->frametime - frametime;
fakeclient->SetTimeBase( flTimeBase );
Q_memset( &cmd, 0, sizeof( cmd ) );
if ( !RunMimicCommand( cmd ) && !bot_zombie.GetBool() )
{
VectorCopy( viewangles, cmd.viewangles );
cmd.forwardmove = forwardmove;
cmd.sidemove = sidemove;
cmd.upmove = upmove;
cmd.buttons = buttons;
cmd.impulse = impulse;
cmd.random_seed = random->RandomInt( 0, 0x7fffffff );
}
if( bot_crouch.GetInt() )
cmd.buttons |= IN_DUCK;
if ( bot_attack.GetBool() )
cmd.buttons |= IN_ATTACK;
MoveHelperServer()->SetHost( fakeclient );
fakeclient->PlayerRunCommand( &cmd, MoveHelperServer() );
// save off the last good usercmd
fakeclient->SetLastUserCommand( cmd );
// Clear out any fixangle that has been set
fakeclient->pl.fixangle = FIXANGLE_NONE;
// Restore the globals..
gpGlobals->frametime = flOldFrametime;
gpGlobals->curtime = flOldCurtime;
}
//-----------------------------------------------------------------------------
// Purpose: Run this Bot's AI for one frame.
//-----------------------------------------------------------------------------
void Bot_Think( CHL2MP_Player *pBot )
{
// Make sure we stay being a bot
pBot->AddFlag( FL_FAKECLIENT );
botdata_t *botdata = &g_BotData[ ENTINDEX( pBot->edict() ) - 1 ];
QAngle vecViewAngles;
float forwardmove = 0.0;
float sidemove = botdata->sidemove;
float upmove = 0.0;
unsigned short buttons = 0;
byte impulse = 0;
float frametime = gpGlobals->frametime;
vecViewAngles = pBot->GetLocalAngles();
// Create some random values
if ( pBot->IsAlive() && (pBot->GetSolid() == SOLID_BBOX) )
{
trace_t trace;
// Stop when shot
if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) )
{
if ( pBot->m_iHealth == 100 )
{
forwardmove = 600 * ( botdata->backwards ? -1 : 1 );
if ( botdata->sidemove != 0.0f )
{
forwardmove *= random->RandomFloat( 0.1, 1.0f );
}
}
else
{
forwardmove = 0;
}
}
// Only turn if I haven't been hurt
if ( !pBot->IsEFlagSet(EFL_BOT_FROZEN) && pBot->m_iHealth == 100 )
{
Vector vecEnd;
Vector forward;
QAngle angle;
float angledelta = 15.0;
int maxtries = (int)360.0/angledelta;
if ( botdata->lastturntoright )
{
angledelta = -angledelta;
}
angle = pBot->GetLocalAngles();
Vector vecSrc;
while ( --maxtries >= 0 )
{
AngleVectors( angle, &forward );
vecSrc = pBot->GetLocalOrigin() + Vector( 0, 0, 36 );
vecEnd = vecSrc + forward * 10;
UTIL_TraceHull( vecSrc, vecEnd, VEC_HULL_MIN_SCALED( pBot ), VEC_HULL_MAX_SCALED( pBot ),
MASK_PLAYERSOLID, pBot, COLLISION_GROUP_NONE, &trace );
if ( trace.fraction == 1.0 )
{
if ( gpGlobals->curtime < botdata->nextturntime )
{
break;
}
}
angle.y += angledelta;
if ( angle.y > 180 )
angle.y -= 360;
else if ( angle.y < -180 )
angle.y += 360;
botdata->nextturntime = gpGlobals->curtime + 2.0;
botdata->lastturntoright = random->RandomInt( 0, 1 ) == 0 ? true : false;
botdata->forwardAngle = angle;
botdata->lastAngles = angle;
}
if ( gpGlobals->curtime >= botdata->nextstrafetime )
{
botdata->nextstrafetime = gpGlobals->curtime + 1.0f;
if ( random->RandomInt( 0, 5 ) == 0 )
{
botdata->sidemove = -600.0f + 1200.0f * random->RandomFloat( 0, 2 );
}
else
{
botdata->sidemove = 0;
}
sidemove = botdata->sidemove;
if ( random->RandomInt( 0, 20 ) == 0 )
{
botdata->backwards = true;
}
else
{
botdata->backwards = false;
}
}
pBot->SetLocalAngles( angle );
vecViewAngles = angle;
}
// Is my team being forced to defend?
if ( bot_defend.GetInt() == pBot->GetTeamNumber() )
{
buttons |= IN_ATTACK2;
}
// If bots are being forced to fire a weapon, see if I have it
else if ( bot_forcefireweapon.GetString() )
{
CBaseCombatWeapon *pWeapon = pBot->Weapon_OwnsThisType( bot_forcefireweapon.GetString() );
if ( pWeapon )
{
// Switch to it if we don't have it out
CBaseCombatWeapon *pActiveWeapon = pBot->GetActiveWeapon();
// Switch?
if ( pActiveWeapon != pWeapon )
{
pBot->Weapon_Switch( pWeapon );
}
else
{
// Start firing
// Some weapons require releases, so randomise firing
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
{
buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
}
}
}
}
if ( bot_flipout.GetInt() )
{
if ( bot_forceattackon.GetBool() || (RandomFloat(0.0,1.0) > 0.5) )
{
buttons |= bot_forceattack2.GetBool() ? IN_ATTACK2 : IN_ATTACK;
}
}
if ( strlen( bot_sendcmd.GetString() ) > 0 )
{
//send the cmd from this bot
CCommand args;
args.Tokenize( bot_sendcmd.GetString() );
pBot->ClientCommand( args );
bot_sendcmd.SetValue("");
}
}
else
{
// Wait for Reinforcement wave
if ( !pBot->IsAlive() )
{
// Try hitting my buttons occasionally
if ( random->RandomInt( 0, 100 ) > 80 )
{
// Respawn the bot
if ( random->RandomInt( 0, 1 ) == 0 )
{
buttons |= IN_JUMP;
}
else
{
buttons = 0;
}
}
}
}
if ( bot_flipout.GetInt() >= 2 )
{
QAngle angOffset = RandomAngle( -1, 1 );
botdata->lastAngles += angOffset;
for ( int i = 0 ; i < 2; i++ )
{
if ( fabs( botdata->lastAngles[ i ] - botdata->forwardAngle[ i ] ) > 15.0f )
{
if ( botdata->lastAngles[ i ] > botdata->forwardAngle[ i ] )
{
botdata->lastAngles[ i ] = botdata->forwardAngle[ i ] + 15;
}
else
{
botdata->lastAngles[ i ] = botdata->forwardAngle[ i ] - 15;
}
}
}
botdata->lastAngles[ 2 ] = 0;
pBot->SetLocalAngles( botdata->lastAngles );
}
RunPlayerMove( pBot, pBot->GetLocalAngles(), forwardmove, sidemove, upmove, buttons, impulse, frametime );
}
#endif

View File

@ -1,19 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef BOT_BASE_H
#define BOT_BASE_H
#ifdef _WIN32
#pragma once
#endif
// If iTeam or iClass is -1, then a team or class is randomly chosen.
CBasePlayer *BotPutInServer( bool bFrozen, int iTeam );
#endif // BOT_BASE_H

View File

@ -1,201 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
/*
===== tf_client.cpp ========================================================
HL2 client/server game specific stuff
*/
#include "cbase.h"
#include "hl2mp_player.h"
#include "hl2mp_gamerules.h"
#include "gamerules.h"
#include "teamplay_gamerules.h"
#include "entitylist.h"
#include "physics.h"
#include "game.h"
#include "player_resource.h"
#include "engine/IEngineSound.h"
#include "team.h"
#include "viewport_panel_names.h"
#include "tier0/vprof.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
void Host_Say( edict_t *pEdict, bool teamonly );
ConVar sv_motd_unload_on_dismissal( "sv_motd_unload_on_dismissal", "0", 0, "If enabled, the MOTD contents will be unloaded when the player closes the MOTD." );
extern CBaseEntity* FindPickerEntityClass( CBasePlayer *pPlayer, char *classname );
extern bool g_fGameOver;
void FinishClientPutInServer( CHL2MP_Player *pPlayer )
{
pPlayer->InitialSpawn();
pPlayer->Spawn();
char sName[128];
Q_strncpy( sName, pPlayer->GetPlayerName(), sizeof( sName ) );
// First parse the name and remove any %'s
for ( char *pApersand = sName; pApersand != NULL && *pApersand != 0; pApersand++ )
{
// Replace it with a space
if ( *pApersand == '%' )
*pApersand = ' ';
}
// notify other clients of player joining the game
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Game_connected", sName[0] != 0 ? sName : "<unconnected>" );
if ( HL2MPRules()->IsTeamplay() == true )
{
ClientPrint( pPlayer, HUD_PRINTTALK, "You are on team %s1\n", pPlayer->GetTeam()->GetName() );
}
const ConVar *hostname = cvar->FindVar( "hostname" );
const char *title = (hostname) ? hostname->GetString() : "MESSAGE OF THE DAY";
KeyValues *data = new KeyValues("data");
data->SetString( "title", title ); // info panel title
data->SetString( "type", "1" ); // show userdata from stringtable entry
data->SetString( "msg", "motd" ); // use this stringtable entry
data->SetBool( "unload", sv_motd_unload_on_dismissal.GetBool() );
pPlayer->ShowViewPortPanel( PANEL_INFO, true, data );
data->deleteThis();
}
/*
===========
ClientPutInServer
called each time a player is spawned into the game
============
*/
void ClientPutInServer( edict_t *pEdict, const char *playername )
{
// Allocate a CBaseTFPlayer for pev, and call spawn
CHL2MP_Player *pPlayer = CHL2MP_Player::CreatePlayer( "player", pEdict );
pPlayer->SetPlayerName( playername );
}
void ClientActive( edict_t *pEdict, bool bLoadGame )
{
// Can't load games in CS!
Assert( !bLoadGame );
CHL2MP_Player *pPlayer = ToHL2MPPlayer( CBaseEntity::Instance( pEdict ) );
FinishClientPutInServer( pPlayer );
}
/*
===============
const char *GetGameDescription()
Returns the descriptive name of this .dll. E.g., Half-Life, or Team Fortress 2
===============
*/
const char *GetGameDescription()
{
if ( g_pGameRules ) // this function may be called before the world has spawned, and the game rules initialized
return g_pGameRules->GetGameDescription();
else
return "Half-Life 2 Deathmatch";
}
//-----------------------------------------------------------------------------
// Purpose: Given a player and optional name returns the entity of that
// classname that the player is nearest facing
//
// Input :
// Output :
//-----------------------------------------------------------------------------
CBaseEntity* FindEntity( edict_t *pEdict, char *classname)
{
// If no name was given set bits based on the picked
if (FStrEq(classname,""))
{
return (FindPickerEntityClass( static_cast<CBasePlayer*>(GetContainingEntity(pEdict)), classname ));
}
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Precache game-specific models & sounds
//-----------------------------------------------------------------------------
void ClientGamePrecache( void )
{
CBaseEntity::PrecacheModel("models/player.mdl");
CBaseEntity::PrecacheModel( "models/gibs/agibs.mdl" );
CBaseEntity::PrecacheModel ("models/weapons/v_hands.mdl");
CBaseEntity::PrecacheScriptSound( "HUDQuickInfo.LowAmmo" );
CBaseEntity::PrecacheScriptSound( "HUDQuickInfo.LowHealth" );
CBaseEntity::PrecacheScriptSound( "FX_AntlionImpact.ShellImpact" );
CBaseEntity::PrecacheScriptSound( "Missile.ShotDown" );
CBaseEntity::PrecacheScriptSound( "Bullets.DefaultNearmiss" );
CBaseEntity::PrecacheScriptSound( "Bullets.GunshipNearmiss" );
CBaseEntity::PrecacheScriptSound( "Bullets.StriderNearmiss" );
CBaseEntity::PrecacheScriptSound( "Geiger.BeepHigh" );
CBaseEntity::PrecacheScriptSound( "Geiger.BeepLow" );
}
// called by ClientKill and DeadThink
void respawn( CBaseEntity *pEdict, bool fCopyCorpse )
{
CHL2MP_Player *pPlayer = ToHL2MPPlayer( pEdict );
if ( pPlayer )
{
if ( gpGlobals->curtime > pPlayer->GetDeathTime() + DEATH_ANIMATION_TIME )
{
// respawn player
pPlayer->Spawn();
}
else
{
pPlayer->SetNextThink( gpGlobals->curtime + 0.1f );
}
}
}
void GameStartFrame( void )
{
VPROF("GameStartFrame()");
if ( g_fGameOver )
return;
gpGlobals->teamplay = (teamplay.GetInt() != 0);
#ifdef DEBUG
extern void Bot_RunAll();
Bot_RunAll();
#endif
}
//=========================================================
// instantiate the proper game rules object
//=========================================================
void InstallGameRules()
{
// vanilla deathmatch
CreateGameRulesObject( "CHL2MPRules" );
}

View File

@ -1,25 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hl2mp_cvars.h"
// Ready restart
ConVar mp_readyrestart(
"mp_readyrestart",
"0",
FCVAR_GAMEDLL,
"If non-zero, game will restart once each player gives the ready signal" );
// Ready signal
ConVar mp_ready_signal(
"mp_ready_signal",
"ready",
FCVAR_GAMEDLL,
"Text that each player must speak for the match to begin" );

View File

@ -1,20 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef HL2MP_CVARS_H
#define HL2MP_CVARS_H
#ifdef _WIN32
#pragma once
#endif
#define MAX_INTERMISSION_TIME 120
extern ConVar mp_restartround;
extern ConVar mp_readyrestart;
extern ConVar mp_ready_signal;
#endif //HL2MP_CVARS_H

View File

@ -1,32 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "gameinterface.h"
#include "mapentities.h"
#include "hl2mp_gameinterface.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// -------------------------------------------------------------------------------------------- //
// Mod-specific CServerGameClients implementation.
// -------------------------------------------------------------------------------------------- //
void CServerGameClients::GetPlayerLimits( int& minplayers, int& maxplayers, int &defaultMaxPlayers ) const
{
minplayers = defaultMaxPlayers = 2;
maxplayers = 16;
}
// -------------------------------------------------------------------------------------------- //
// Mod-specific CServerGameDLL implementation.
// -------------------------------------------------------------------------------------------- //
void CServerGameDLL::LevelInit_ParseAllEntities( const char *pMapEntities )
{
}

View File

@ -1,10 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#ifndef HL2MP_GAMEINTERFACE_H
#define HL2MP_GAMEINTERFACE_H
#ifdef _WIN32
#pragma once
#endif
#include "gameinterface.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,176 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef HL2MP_PLAYER_H
#define HL2MP_PLAYER_H
#pragma once
class CHL2MP_Player;
#include "basemultiplayerplayer.h"
#include "hl2_playerlocaldata.h"
#include "hl2_player.h"
#include "simtimer.h"
#include "soundenvelope.h"
#include "hl2mp_player_shared.h"
#include "hl2mp_gamerules.h"
#include "utldict.h"
//=============================================================================
// >> HL2MP_Player
//=============================================================================
class CHL2MPPlayerStateInfo
{
public:
HL2MPPlayerState m_iPlayerState;
const char *m_pStateName;
void (CHL2MP_Player::*pfnEnterState)(); // Init and deinit the state.
void (CHL2MP_Player::*pfnLeaveState)();
void (CHL2MP_Player::*pfnPreThink)(); // Do a PreThink() in this state.
};
class CHL2MP_Player : public CHL2_Player
{
public:
DECLARE_CLASS( CHL2MP_Player, CHL2_Player );
CHL2MP_Player();
~CHL2MP_Player( void );
static CHL2MP_Player *CreatePlayer( const char *className, edict_t *ed )
{
CHL2MP_Player::s_PlayerEdict = ed;
return (CHL2MP_Player*)CreateEntityByName( className );
}
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
virtual void Precache( void );
virtual void Spawn( void );
virtual void PostThink( void );
virtual void PreThink( void );
virtual void PlayerDeathThink( void );
virtual void SetAnimation( PLAYER_ANIM playerAnim );
virtual bool HandleCommand_JoinTeam( int team );
virtual bool ClientCommand( const CCommand &args );
virtual void CreateViewModel( int viewmodelindex = 0 );
virtual bool BecomeRagdollOnClient( const Vector &force );
virtual void Event_Killed( const CTakeDamageInfo &info );
virtual int OnTakeDamage( const CTakeDamageInfo &inputInfo );
virtual bool WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const;
virtual void FireBullets ( const FireBulletsInfo_t &info );
virtual bool Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex = 0);
virtual bool BumpWeapon( CBaseCombatWeapon *pWeapon );
virtual void ChangeTeam( int iTeam );
virtual void PickupObject ( CBaseEntity *pObject, bool bLimitMassAndSize );
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
virtual void Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector *pvecTarget = NULL, const Vector *pVelocity = NULL );
virtual void UpdateOnRemove( void );
virtual void DeathSound( const CTakeDamageInfo &info );
virtual CBaseEntity* EntSelectSpawnPoint( void );
int FlashlightIsOn( void );
void FlashlightTurnOn( void );
void FlashlightTurnOff( void );
void PrecacheFootStepSounds( void );
bool ValidatePlayerModel( const char *pModel );
QAngle GetAnimEyeAngles( void ) { return m_angEyeAngles.Get(); }
Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL );
void CheatImpulseCommands( int iImpulse );
void CreateRagdollEntity( void );
void GiveAllItems( void );
void GiveDefaultItems( void );
void NoteWeaponFired( void );
void ResetAnimation( void );
void SetPlayerModel( void );
void SetPlayerTeamModel( void );
Activity TranslateTeamActivity( Activity ActToTranslate );
float GetNextModelChangeTime( void ) { return m_flNextModelChangeTime; }
float GetNextTeamChangeTime( void ) { return m_flNextTeamChangeTime; }
void PickDefaultSpawnTeam( void );
void SetupPlayerSoundsByModel( const char *pModelName );
const char *GetPlayerModelSoundPrefix( void );
int GetPlayerModelType( void ) { return m_iPlayerSoundType; }
void DetonateTripmines( void );
void Reset();
bool IsReady();
void SetReady( bool bReady );
void CheckChatText( char *p, int bufsize );
void State_Transition( HL2MPPlayerState newState );
void State_Enter( HL2MPPlayerState newState );
void State_Leave();
void State_PreThink();
CHL2MPPlayerStateInfo *State_LookupInfo( HL2MPPlayerState state );
void State_Enter_ACTIVE();
void State_PreThink_ACTIVE();
void State_Enter_OBSERVER_MODE();
void State_PreThink_OBSERVER_MODE();
virtual bool StartObserverMode( int mode );
virtual void StopObserverMode( void );
Vector m_vecTotalBulletForce; //Accumulator for bullet force in a single frame
// Tracks our ragdoll entity.
CNetworkHandle( CBaseEntity, m_hRagdoll ); // networked entity handle
virtual bool CanHearAndReadChatFrom( CBasePlayer *pPlayer );
private:
CNetworkQAngle( m_angEyeAngles );
CPlayerAnimState m_PlayerAnimState;
int m_iLastWeaponFireUsercmd;
int m_iModelType;
CNetworkVar( int, m_iSpawnInterpCounter );
CNetworkVar( int, m_iPlayerSoundType );
float m_flNextModelChangeTime;
float m_flNextTeamChangeTime;
float m_flSlamProtectTime;
HL2MPPlayerState m_iPlayerState;
CHL2MPPlayerStateInfo *m_pCurStateInfo;
bool ShouldRunRateLimitedCommand( const CCommand &args );
// This lets us rate limit the commands the players can execute so they don't overflow things like reliable buffers.
CUtlDict<float,int> m_RateLimitLastCommandTimes;
bool m_bEnterObserver;
bool m_bReady;
};
inline CHL2MP_Player *ToHL2MPPlayer( CBaseEntity *pEntity )
{
if ( !pEntity || !pEntity->IsPlayer() )
return NULL;
return dynamic_cast<CHL2MP_Player*>( pEntity );
}
#endif //HL2MP_PLAYER_H

View File

@ -1,104 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "basetempentity.h"
#define NUM_BULLET_SEED_BITS 8
//-----------------------------------------------------------------------------
// Purpose: Display's a blood sprite
//-----------------------------------------------------------------------------
class CTEHL2MPFireBullets : public CBaseTempEntity
{
public:
DECLARE_CLASS( CTEHL2MPFireBullets, CBaseTempEntity );
DECLARE_SERVERCLASS();
CTEHL2MPFireBullets( const char *name );
virtual ~CTEHL2MPFireBullets( void );
public:
CNetworkVar( int, m_iPlayer );
CNetworkVector( m_vecOrigin );
CNetworkVector( m_vecDir );
CNetworkVar( int, m_iAmmoID );
CNetworkVar( int, m_iSeed );
CNetworkVar( int, m_iShots );
CNetworkVar( float, m_flSpread );
CNetworkVar( bool, m_bDoImpacts );
CNetworkVar( bool, m_bDoTracers );
};
//-----------------------------------------------------------------------------
// Purpose:
// Input : *name -
//-----------------------------------------------------------------------------
CTEHL2MPFireBullets::CTEHL2MPFireBullets( const char *name ) :
CBaseTempEntity( name )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CTEHL2MPFireBullets::~CTEHL2MPFireBullets( void )
{
}
IMPLEMENT_SERVERCLASS_ST_NOBASE(CTEHL2MPFireBullets, DT_TEHL2MPFireBullets)
SendPropVector( SENDINFO(m_vecOrigin), -1, SPROP_COORD ),
SendPropVector( SENDINFO(m_vecDir), -1 ),
SendPropInt( SENDINFO( m_iAmmoID ), 5, SPROP_UNSIGNED ),
SendPropInt( SENDINFO( m_iSeed ), NUM_BULLET_SEED_BITS, SPROP_UNSIGNED ),
SendPropInt( SENDINFO( m_iShots ), 5, SPROP_UNSIGNED ),
SendPropInt( SENDINFO( m_iPlayer ), 6, SPROP_UNSIGNED ), // max 64 players, see MAX_PLAYERS
SendPropFloat( SENDINFO( m_flSpread ), 10, 0, 0, 1 ),
SendPropBool( SENDINFO( m_bDoImpacts ) ),
SendPropBool( SENDINFO( m_bDoTracers ) ),
END_SEND_TABLE()
// Singleton
static CTEHL2MPFireBullets g_TEHL2MPFireBullets( "Shotgun Shot" );
void TE_HL2MPFireBullets(
int iPlayerIndex,
const Vector &vOrigin,
const Vector &vDir,
int iAmmoID,
int iSeed,
int iShots,
float flSpread,
bool bDoTracers,
bool bDoImpacts )
{
CPASFilter filter( vOrigin );
filter.UsePredictionRules();
g_TEHL2MPFireBullets.m_iPlayer = iPlayerIndex;
g_TEHL2MPFireBullets.m_vecOrigin = vOrigin;
g_TEHL2MPFireBullets.m_vecDir = vDir;
g_TEHL2MPFireBullets.m_iSeed = iSeed;
g_TEHL2MPFireBullets.m_iShots = iShots;
g_TEHL2MPFireBullets.m_flSpread = flSpread;
g_TEHL2MPFireBullets.m_iAmmoID = iAmmoID;
g_TEHL2MPFireBullets.m_bDoTracers = bDoTracers;
g_TEHL2MPFireBullets.m_bDoImpacts = bDoImpacts;
Assert( iSeed < (1 << NUM_BULLET_SEED_BITS) );
g_TEHL2MPFireBullets.Create( filter, 0 );
}

View File

@ -1,26 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef TE_HL2MP_SHOTGUN_SHOT_H
#define TE_HL2MP_SHOTGUN_SHOT_H
#ifdef _WIN32
#pragma once
#endif
void TE_HL2MPFireBullets(
int iPlayerIndex,
const Vector &vOrigin,
const Vector &vDir,
int iAmmoID,
int iSeed,
int iShots,
float flSpread,
bool bDoTracers,
bool bDoImpacts );
#endif // TE_HL2MP_SHOTGUN_SHOT_H

View File

@ -19,7 +19,7 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<TargetName>server</TargetName>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@ -58,9 +58,6 @@
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</PostBuildEventUseInBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PreBuildEvent>
<Command>if EXIST ..\..\..\game\mod_episodic\bin\.\$(TargetFileName) for /f "delims=" %%A in ('attrib "..\..\..\game\mod_episodic\bin\.\$(TargetFileName)"') do set valveTmpIsReadOnly="%%A"
@ -74,7 +71,7 @@ if ERRORLEVEL 1 exit /b 1
<AdditionalOptions>/Zm200 /Gw</AdditionalOptions>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\common;..\..\public;..\..\public\tier0;..\..\public\tier1;..\..\game\server\generated_proto_mod_episodic;..\..\thirdparty\protobuf-2.3.0\src;.\;..\..\game\shared;..\..\utils\common;..\..\game\shared\econ;..\..\game\server\NextBot;..\..\game\shared\hl2;..\..\game\shared\episodic;.\hl2;.\episodic</AdditionalIncludeDirectories>
<PreprocessorDefinitions>VPC;RAD_TELEMETRY_DISABLED;_HAS_ITERATOR_DEBUGGING=0;WIN32;_WIN32;_DEBUG;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions);COMPILER_MSVC32;COMPILER_MSVC32;COMPILER_MSVC;_DLL_EXT=.dll;DLLNAME=server;BINK_VIDEO;AVI_VIDEO;WMV_VIDEO;DEV_BUILD;FRAME_POINTER_OMISSION_DISABLED;GAME_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;sprintf=use_Q_snprintf_instead_of_sprintf;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead;fopen=dont_use_fopen;HL2_DLL;HL2_EPISODIC;USES_SAVERESTORE;_EXTERNAL_DLL_EXT=.dll;VPCGAMECAPS=VALVE;PROJECTDIR=C:\sourceproject\halflife2chaos\sp\src\game\server;_DLL_EXT=.dll;VPCGAME=valve;SOURCE1=1</PreprocessorDefinitions>
<PreprocessorDefinitions>VPC;RAD_TELEMETRY_DISABLED;_HAS_ITERATOR_DEBUGGING=0;WIN32;_WIN32;_DEBUG;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions);COMPILER_MSVC32;COMPILER_MSVC32;COMPILER_MSVC;_DLL_EXT=.dll;DLLNAME=server;BINK_VIDEO;AVI_VIDEO;WMV_VIDEO;DEV_BUILD;FRAME_POINTER_OMISSION_DISABLED;GAME_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;sprintf=use_Q_snprintf_instead_of_sprintf;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead;fopen=dont_use_fopen;HL2_DLL;HL2_EPISODIC;USES_SAVERESTORE;_EXTERNAL_DLL_EXT=.dll;VPCGAMECAPS=VALVE;PROJECTDIR=C:\sourceproject\halflife2chaos\sp\src\game\server;_DLL_EXT=.dll;SOURCE1=1;VPCGAME=valve</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
@ -100,7 +97,6 @@ if ERRORLEVEL 1 exit /b 1
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BrowseInformationFile>$(IntDir)/</BrowseInformationFile>
<ErrorReporting>Prompt</ErrorReporting>
<EnablePREfast>true</EnablePREfast>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>;_DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -119,8 +115,7 @@ if ERRORLEVEL 1 exit /b 1
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)/$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<BaseAddress>
</BaseAddress>
<BaseAddress> </BaseAddress>
<TargetMachine>MachineX86</TargetMachine>
<LinkErrorReporting>PromptImmediately</LinkErrorReporting>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
@ -174,7 +169,7 @@ if ERRORLEVEL 1 exit /b 1
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\common;..\..\public;..\..\public\tier0;..\..\public\tier1;..\..\game\server\generated_proto_mod_episodic;..\..\thirdparty\protobuf-2.3.0\src;.\;..\..\game\shared;..\..\utils\common;..\..\game\shared\econ;..\..\game\server\NextBot;..\..\game\shared\hl2;..\..\game\shared\episodic;.\hl2;.\episodic</AdditionalIncludeDirectories>
<PreprocessorDefinitions>VPC;RAD_TELEMETRY_DISABLED;WIN32;_WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions);COMPILER_MSVC32;COMPILER_MSVC32;COMPILER_MSVC;_DLL_EXT=.dll;DLLNAME=server;BINK_VIDEO;AVI_VIDEO;WMV_VIDEO;DEV_BUILD;FRAME_POINTER_OMISSION_DISABLED;GAME_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;sprintf=use_Q_snprintf_instead_of_sprintf;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead;fopen=dont_use_fopen;HL2_DLL;HL2_EPISODIC;USES_SAVERESTORE;_EXTERNAL_DLL_EXT=.dll;VPCGAMECAPS=VALVE;PROJECTDIR=C:\sourceproject\halflife2chaos\sp\src\game\server;_DLL_EXT=.dll;VPCGAME=valve;SOURCE1=1</PreprocessorDefinitions>
<PreprocessorDefinitions>VPC;RAD_TELEMETRY_DISABLED;WIN32;_WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions);COMPILER_MSVC32;COMPILER_MSVC32;COMPILER_MSVC;_DLL_EXT=.dll;DLLNAME=server;BINK_VIDEO;AVI_VIDEO;WMV_VIDEO;DEV_BUILD;FRAME_POINTER_OMISSION_DISABLED;GAME_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;sprintf=use_Q_snprintf_instead_of_sprintf;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead;fopen=dont_use_fopen;HL2_DLL;HL2_EPISODIC;USES_SAVERESTORE;_EXTERNAL_DLL_EXT=.dll;VPCGAMECAPS=VALVE;PROJECTDIR=C:\sourceproject\halflife2chaos\sp\src\game\server;_DLL_EXT=.dll;SOURCE1=1;VPCGAME=valve</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@ -220,8 +215,7 @@ if ERRORLEVEL 1 exit /b 1
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
<BaseAddress>
</BaseAddress>
<BaseAddress> </BaseAddress>
<TargetMachine>MachineX86</TargetMachine>
<LinkErrorReporting>PromptImmediately</LinkErrorReporting>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
@ -814,6 +808,7 @@ exit 1
<ClInclude Include="hl2\npc_manhack.h" />
<ClInclude Include="hl2\npc_metropolice.h" />
<ClInclude Include="hl2\npc_playercompanion.h" />
<ClInclude Include="hl2\npc_PoisonZombie.h" />
<ClInclude Include="hl2\npc_rollermine.h" />
<ClInclude Include="hl2\npc_scanner.h" />
<ClInclude Include="hl2\npc_stalker.h" />
@ -832,6 +827,7 @@ exit 1
<ClInclude Include="hl2\weapon_crowbar.h" />
<ClInclude Include="hl2\weapon_physcannon.h" />
<ClInclude Include="hl2\weapon_rpg.h" />
<ClInclude Include="hl2\weapon_slam.h" />
<ClInclude Include="episodic\weapon_striderbuster.h" />
<ClInclude Include="hl2\weapon_stunstick.h" />
<ClInclude Include="hl2\grenade_beam.h" />
@ -1447,6 +1443,7 @@ exit 1
<ClCompile Include="hl2\weapon_pistol.cpp" />
<ClCompile Include="hl2\weapon_rpg.cpp" />
<ClCompile Include="hl2\weapon_shotgun.cpp" />
<ClCompile Include="hl2\weapon_slam.cpp" />
<ClCompile Include="hl2\weapon_smg1.cpp" />
<ClCompile Include="episodic\weapon_striderbuster.cpp" />
<ClCompile Include="hl2\weapon_stunstick.cpp" />
@ -1522,10 +1519,10 @@ exit 1
<ItemGroup>
<CustomBuild Include="..\..\public\tier0\pointeroverride.asm">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Compiling pointeroverride.asm</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(VCInstallDir)bin\ml.exe" /safeseh /c /Cp /Zi /Fo"$(IntDir)\%(Filename).obj" "%(FullPath)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">&quot;$(VCInstallDir)bin\ml.exe&quot; /safeseh /c /Cp /Zi /Fo&quot;$(IntDir)\%(Filename).obj&quot; &quot;%(FullPath)&quot;</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)\%(Filename).obj</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compiling pointeroverride.asm</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(VCInstallDir)bin\ml.exe" /safeseh /c /Cp /Zi /Fo"$(IntDir)\%(Filename).obj" "%(FullPath)"</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">&quot;$(VCInstallDir)bin\ml.exe&quot; /safeseh /c /Cp /Zi /Fo&quot;$(IntDir)\%(Filename).obj&quot; &quot;%(FullPath)&quot;</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)\%(Filename).obj</Outputs>
</CustomBuild>
<CustomBuild Include="server_episodic.vpc">

View File

@ -1748,6 +1748,9 @@
<ClInclude Include="hl2\weapon_rpg.h">
<Filter>Source Files\HL2 DLL</Filter>
</ClInclude>
<ClInclude Include="hl2\weapon_slam.h">
<Filter>Source Files\HL2 DLL</Filter>
</ClInclude>
<ClInclude Include="episodic\weapon_striderbuster.h">
<Filter>Source Files\HL2 DLL</Filter>
</ClInclude>
@ -3319,6 +3322,9 @@
<ClCompile Include="hl2\weapon_shotgun.cpp">
<Filter>Source Files\HL2 DLL</Filter>
</ClCompile>
<ClCompile Include="hl2\weapon_slam.cpp">
<Filter>Source Files\HL2 DLL</Filter>
</ClCompile>
<ClCompile Include="hl2\weapon_smg1.cpp">
<Filter>Source Files\HL2 DLL</Filter>
</ClCompile>

View File

@ -1,7 +1,7 @@
[vpc crc file version 2]
8209bbc3 C:\sourceproject\halflife2chaos\sp\src\devtools\bin\vpc.exe
_Nc_VS2013/vpcgame:valve_
2919ad95 server_episodic.vpc
2cf78c7c server_episodic.vpc
cd2921c2 ..\..\game\server\server_base.vpc
4832e67a ..\..\vpc_scripts\source_dll_base.vpc
d752cf80 ..\..\vpc_scripts\platform_dirs.vpc

View File

@ -263,6 +263,8 @@ $Project "Server (Episodic)"
$File "hl2\weapon_pistol.cpp"
$File "hl2\weapon_rpg.cpp"
$File "hl2\weapon_rpg.h"
$File "hl2\weapon_slam.cpp"
$File "hl2\weapon_slam.h"
$File "hl2\weapon_shotgun.cpp"
$File "hl2\weapon_smg1.cpp"
$File "episodic\weapon_oldmanharpoon.cpp"

View File

@ -19,7 +19,7 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<TargetName>server</TargetName>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@ -58,9 +58,6 @@
<GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</PostBuildEventUseInBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PreBuildEvent>
<Command>if EXIST ..\..\..\game\mod_hl2\bin\.\$(TargetFileName) for /f "delims=" %%A in ('attrib "..\..\..\game\mod_hl2\bin\.\$(TargetFileName)"') do set valveTmpIsReadOnly="%%A"
@ -74,7 +71,7 @@ if ERRORLEVEL 1 exit /b 1
<AdditionalOptions>/Zm200 /Gw</AdditionalOptions>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\common;..\..\public;..\..\public\tier0;..\..\public\tier1;..\..\game\server\generated_proto_mod_hl2;..\..\thirdparty\protobuf-2.3.0\src;.\;..\..\game\shared;..\..\utils\common;..\..\game\shared\econ;..\..\game\server\NextBot;..\..\game\shared\hl2;.\hl2</AdditionalIncludeDirectories>
<PreprocessorDefinitions>VPC;RAD_TELEMETRY_DISABLED;_HAS_ITERATOR_DEBUGGING=0;WIN32;_WIN32;_DEBUG;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions);COMPILER_MSVC32;COMPILER_MSVC32;COMPILER_MSVC;_DLL_EXT=.dll;DLLNAME=server;BINK_VIDEO;AVI_VIDEO;WMV_VIDEO;DEV_BUILD;FRAME_POINTER_OMISSION_DISABLED;GAME_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;sprintf=use_Q_snprintf_instead_of_sprintf;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead;fopen=dont_use_fopen;HL2_DLL;USES_SAVERESTORE;_EXTERNAL_DLL_EXT=.dll;VPCGAMECAPS=VALVE;PROJECTDIR=C:\sourceproject\halflife2chaos\sp\src\game\server;_DLL_EXT=.dll;VPCGAME=valve;SOURCE1=1</PreprocessorDefinitions>
<PreprocessorDefinitions>VPC;RAD_TELEMETRY_DISABLED;_HAS_ITERATOR_DEBUGGING=0;WIN32;_WIN32;_DEBUG;DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions);COMPILER_MSVC32;COMPILER_MSVC32;COMPILER_MSVC;_DLL_EXT=.dll;DLLNAME=server;BINK_VIDEO;AVI_VIDEO;WMV_VIDEO;DEV_BUILD;FRAME_POINTER_OMISSION_DISABLED;GAME_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;sprintf=use_Q_snprintf_instead_of_sprintf;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead;fopen=dont_use_fopen;HL2_DLL;USES_SAVERESTORE;_EXTERNAL_DLL_EXT=.dll;VPCGAMECAPS=VALVE;PROJECTDIR=C:\sourceproject\halflife2chaos\sp\src\game\server;_DLL_EXT=.dll;SOURCE1=1;VPCGAME=valve</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
@ -100,7 +97,6 @@ if ERRORLEVEL 1 exit /b 1
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BrowseInformationFile>$(IntDir)/</BrowseInformationFile>
<ErrorReporting>Prompt</ErrorReporting>
<EnablePREfast>true</EnablePREfast>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>;_DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -119,8 +115,7 @@ if ERRORLEVEL 1 exit /b 1
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)/$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<BaseAddress>
</BaseAddress>
<BaseAddress> </BaseAddress>
<TargetMachine>MachineX86</TargetMachine>
<LinkErrorReporting>PromptImmediately</LinkErrorReporting>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
@ -170,7 +165,7 @@ if ERRORLEVEL 1 exit /b 1
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\common;..\..\public;..\..\public\tier0;..\..\public\tier1;..\..\game\server\generated_proto_mod_hl2;..\..\thirdparty\protobuf-2.3.0\src;.\;..\..\game\shared;..\..\utils\common;..\..\game\shared\econ;..\..\game\server\NextBot;..\..\game\shared\hl2;.\hl2</AdditionalIncludeDirectories>
<PreprocessorDefinitions>VPC;RAD_TELEMETRY_DISABLED;WIN32;_WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions);COMPILER_MSVC32;COMPILER_MSVC32;COMPILER_MSVC;_DLL_EXT=.dll;DLLNAME=server;BINK_VIDEO;AVI_VIDEO;WMV_VIDEO;DEV_BUILD;FRAME_POINTER_OMISSION_DISABLED;GAME_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;sprintf=use_Q_snprintf_instead_of_sprintf;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead;fopen=dont_use_fopen;HL2_DLL;USES_SAVERESTORE;_EXTERNAL_DLL_EXT=.dll;VPCGAMECAPS=VALVE;PROJECTDIR=C:\sourceproject\halflife2chaos\sp\src\game\server;_DLL_EXT=.dll;VPCGAME=valve;SOURCE1=1</PreprocessorDefinitions>
<PreprocessorDefinitions>VPC;RAD_TELEMETRY_DISABLED;WIN32;_WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_RUNTIME_LIBRARY_MISMATCH;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_MSC_VER_MISMATCH;%(PreprocessorDefinitions);COMPILER_MSVC32;COMPILER_MSVC32;COMPILER_MSVC;_DLL_EXT=.dll;DLLNAME=server;BINK_VIDEO;AVI_VIDEO;WMV_VIDEO;DEV_BUILD;FRAME_POINTER_OMISSION_DISABLED;GAME_DLL;VECTOR;VERSION_SAFE_STEAM_API_INTERFACES;PROTECTED_THINGS_ENABLE;sprintf=use_Q_snprintf_instead_of_sprintf;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead;fopen=dont_use_fopen;HL2_DLL;USES_SAVERESTORE;_EXTERNAL_DLL_EXT=.dll;VPCGAMECAPS=VALVE;PROJECTDIR=C:\sourceproject\halflife2chaos\sp\src\game\server;_DLL_EXT=.dll;SOURCE1=1;VPCGAME=valve</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@ -216,8 +211,7 @@ if ERRORLEVEL 1 exit /b 1
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
<BaseAddress>
</BaseAddress>
<BaseAddress> </BaseAddress>
<TargetMachine>MachineX86</TargetMachine>
<LinkErrorReporting>PromptImmediately</LinkErrorReporting>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
@ -800,6 +794,7 @@ exit 1
<ClInclude Include="hl2\npc_manhack.h" />
<ClInclude Include="hl2\npc_metropolice.h" />
<ClInclude Include="hl2\npc_playercompanion.h" />
<ClInclude Include="hl2\npc_PoisonZombie.h" />
<ClInclude Include="hl2\npc_rollermine.h" />
<ClInclude Include="hl2\npc_scanner.h" />
<ClInclude Include="hl2\npc_stalker.h" />
@ -819,6 +814,7 @@ exit 1
<ClInclude Include="hl2\weapon_crowbar.h" />
<ClInclude Include="hl2\weapon_physcannon.h" />
<ClInclude Include="hl2\weapon_rpg.h" />
<ClInclude Include="hl2\weapon_slam.h" />
<ClInclude Include="hl2\weapon_stunstick.h" />
<ClInclude Include="hl2\grenade_beam.h" />
<ClInclude Include="hl2\grenade_homer.h" />
@ -1410,6 +1406,7 @@ exit 1
<ClCompile Include="hl2\weapon_pistol.cpp" />
<ClCompile Include="hl2\weapon_rpg.cpp" />
<ClCompile Include="hl2\weapon_shotgun.cpp" />
<ClCompile Include="hl2\weapon_slam.cpp" />
<ClCompile Include="hl2\weapon_smg1.cpp" />
<ClCompile Include="hl2\weapon_stunstick.cpp" />
<ClCompile Include="hl2\grenade_beam.cpp" />

View File

@ -1733,6 +1733,9 @@
<ClInclude Include="hl2\weapon_rpg.h">
<Filter>Source Files\HL2 DLL</Filter>
</ClInclude>
<ClInclude Include="hl2\weapon_slam.h">
<Filter>Source Files\HL2 DLL</Filter>
</ClInclude>
<ClInclude Include="hl2\weapon_stunstick.h">
<Filter>Source Files\HL2 DLL</Filter>
</ClInclude>
@ -3250,6 +3253,9 @@
<ClCompile Include="hl2\weapon_shotgun.cpp">
<Filter>Source Files\HL2 DLL</Filter>
</ClCompile>
<ClCompile Include="hl2\weapon_slam.cpp">
<Filter>Source Files\HL2 DLL</Filter>
</ClCompile>
<ClCompile Include="hl2\weapon_smg1.cpp">
<Filter>Source Files\HL2 DLL</Filter>
</ClCompile>

View File

@ -1,7 +1,7 @@
[vpc crc file version 2]
8209bbc3 C:\sourceproject\halflife2chaos\sp\src\devtools\bin\vpc.exe
_Nc_VS2013/vpcgame:valve_
ad055d7e server_hl2.vpc
bcc57729 server_hl2.vpc
cd2921c2 ..\..\game\server\server_base.vpc
4832e67a ..\..\vpc_scripts\source_dll_base.vpc
d752cf80 ..\..\vpc_scripts\platform_dirs.vpc

View File

@ -248,6 +248,8 @@ $Project "Server (HL2)"
$File "hl2\weapon_pistol.cpp"
$File "hl2\weapon_rpg.cpp"
$File "hl2\weapon_rpg.h"
$File "hl2\weapon_slam.cpp"
$File "hl2\weapon_slam.h"
$File "hl2\weapon_shotgun.cpp"
$File "hl2\weapon_smg1.cpp"
$File "hl2\weapon_stunstick.cpp"

File diff suppressed because it is too large Load Diff

View File

@ -1,172 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#ifndef HL2MP_GAMERULES_H
#define HL2MP_GAMERULES_H
#pragma once
#include "gamerules.h"
#include "teamplay_gamerules.h"
#include "gamevars_shared.h"
#ifndef CLIENT_DLL
#include "hl2mp_player.h"
#endif
#define VEC_CROUCH_TRACE_MIN HL2MPRules()->GetHL2MPViewVectors()->m_vCrouchTraceMin
#define VEC_CROUCH_TRACE_MAX HL2MPRules()->GetHL2MPViewVectors()->m_vCrouchTraceMax
enum
{
TEAM_COMBINE = 2,
TEAM_REBELS,
};
#ifdef CLIENT_DLL
#define CHL2MPRules C_HL2MPRules
#define CHL2MPGameRulesProxy C_HL2MPGameRulesProxy
#endif
class CHL2MPGameRulesProxy : public CGameRulesProxy
{
public:
DECLARE_CLASS( CHL2MPGameRulesProxy, CGameRulesProxy );
DECLARE_NETWORKCLASS();
};
class HL2MPViewVectors : public CViewVectors
{
public:
HL2MPViewVectors(
Vector vView,
Vector vHullMin,
Vector vHullMax,
Vector vDuckHullMin,
Vector vDuckHullMax,
Vector vDuckView,
Vector vObsHullMin,
Vector vObsHullMax,
Vector vDeadViewHeight,
Vector vCrouchTraceMin,
Vector vCrouchTraceMax ) :
CViewVectors(
vView,
vHullMin,
vHullMax,
vDuckHullMin,
vDuckHullMax,
vDuckView,
vObsHullMin,
vObsHullMax,
vDeadViewHeight )
{
m_vCrouchTraceMin = vCrouchTraceMin;
m_vCrouchTraceMax = vCrouchTraceMax;
}
Vector m_vCrouchTraceMin;
Vector m_vCrouchTraceMax;
};
class CHL2MPRules : public CTeamplayRules
{
public:
DECLARE_CLASS( CHL2MPRules, CTeamplayRules );
#ifdef CLIENT_DLL
DECLARE_CLIENTCLASS_NOBASE(); // This makes datatables able to access our private vars.
#else
DECLARE_SERVERCLASS_NOBASE(); // This makes datatables able to access our private vars.
#endif
CHL2MPRules();
virtual ~CHL2MPRules();
virtual void Precache( void );
virtual bool ShouldCollide( int collisionGroup0, int collisionGroup1 );
virtual bool ClientCommand( CBaseEntity *pEdict, const CCommand &args );
virtual float FlWeaponRespawnTime( CBaseCombatWeapon *pWeapon );
virtual float FlWeaponTryRespawn( CBaseCombatWeapon *pWeapon );
virtual Vector VecWeaponRespawnSpot( CBaseCombatWeapon *pWeapon );
virtual int WeaponShouldRespawn( CBaseCombatWeapon *pWeapon );
virtual void Think( void );
virtual void CreateStandardEntities( void );
virtual void ClientSettingsChanged( CBasePlayer *pPlayer );
virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget );
virtual void GoToIntermission( void );
virtual void DeathNotice( CBasePlayer *pVictim, const CTakeDamageInfo &info );
virtual const char *GetGameDescription( void );
// derive this function if you mod uses encrypted weapon info files
virtual const unsigned char *GetEncryptionKey( void ) { return (unsigned char *)"x9Ke0BY7"; }
virtual const CViewVectors* GetViewVectors() const;
const HL2MPViewVectors* GetHL2MPViewVectors() const;
float GetMapRemainingTime();
void CleanUpMap();
void CheckRestartGame();
void RestartGame();
#ifndef CLIENT_DLL
virtual Vector VecItemRespawnSpot( CItem *pItem );
virtual QAngle VecItemRespawnAngles( CItem *pItem );
virtual float FlItemRespawnTime( CItem *pItem );
virtual bool CanHavePlayerItem( CBasePlayer *pPlayer, CBaseCombatWeapon *pItem );
virtual bool FShouldSwitchWeapon( CBasePlayer *pPlayer, CBaseCombatWeapon *pWeapon );
void AddLevelDesignerPlacedObject( CBaseEntity *pEntity );
void RemoveLevelDesignerPlacedObject( CBaseEntity *pEntity );
void ManageObjectRelocation( void );
void CheckChatForReadySignal( CHL2MP_Player *pPlayer, const char *chatmsg );
const char *GetChatFormat( bool bTeamOnly, CBasePlayer *pPlayer );
#endif
virtual void ClientDisconnected( edict_t *pClient );
bool CheckGameOver( void );
bool IsIntermission( void );
void PlayerKilled( CBasePlayer *pVictim, const CTakeDamageInfo &info );
bool IsTeamplay( void ) { return m_bTeamPlayEnabled; }
void CheckAllPlayersReady( void );
virtual bool IsConnectedUserInfoChangeAllowed( CBasePlayer *pPlayer );
private:
CNetworkVar( bool, m_bTeamPlayEnabled );
CNetworkVar( float, m_flGameStartTime );
CUtlVector<EHANDLE> m_hRespawnableItemsAndWeapons;
float m_tmNextPeriodicThink;
float m_flRestartGameTime;
bool m_bCompleteReset;
bool m_bAwaitingReadyRestart;
bool m_bHeardAllPlayersReady;
#ifndef CLIENT_DLL
bool m_bChangelevelDone;
#endif
};
inline CHL2MPRules* HL2MPRules()
{
return static_cast<CHL2MPRules*>(g_pGameRules);
}
#endif //HL2MP_GAMERULES_H

View File

@ -1,577 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "prediction.h"
#define CRecipientFilter C_RecipientFilter
#else
#include "hl2mp_player.h"
#endif
#include "engine/IEngineSound.h"
#include "SoundEmitterSystem/isoundemittersystembase.h"
extern ConVar sv_footsteps;
const char *g_ppszPlayerSoundPrefixNames[PLAYER_SOUNDS_MAX] =
{
"NPC_Citizen",
"NPC_CombineS",
"NPC_MetroPolice",
};
const char *CHL2MP_Player::GetPlayerModelSoundPrefix( void )
{
return g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType];
}
void CHL2MP_Player::PrecacheFootStepSounds( void )
{
int iFootstepSounds = ARRAYSIZE( g_ppszPlayerSoundPrefixNames );
int i;
for ( i = 0; i < iFootstepSounds; ++i )
{
char szFootStepName[128];
Q_snprintf( szFootStepName, sizeof( szFootStepName ), "%s.RunFootstepLeft", g_ppszPlayerSoundPrefixNames[i] );
PrecacheScriptSound( szFootStepName );
Q_snprintf( szFootStepName, sizeof( szFootStepName ), "%s.RunFootstepRight", g_ppszPlayerSoundPrefixNames[i] );
PrecacheScriptSound( szFootStepName );
}
}
//-----------------------------------------------------------------------------
// Consider the weapon's built-in accuracy, this character's proficiency with
// the weapon, and the status of the target. Use this information to determine
// how accurately to shoot at the target.
//-----------------------------------------------------------------------------
Vector CHL2MP_Player::GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget )
{
if ( pWeapon )
return pWeapon->GetBulletSpread( WEAPON_PROFICIENCY_PERFECT );
return VECTOR_CONE_15DEGREES;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : step -
// fvol -
// force - force sound to play
//-----------------------------------------------------------------------------
void CHL2MP_Player::PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force )
{
if ( gpGlobals->maxClients > 1 && !sv_footsteps.GetFloat() )
return;
#if defined( CLIENT_DLL )
// during prediction play footstep sounds only once
if ( !prediction->IsFirstTimePredicted() )
return;
#endif
if ( GetFlags() & FL_DUCKING )
return;
m_Local.m_nStepside = !m_Local.m_nStepside;
char szStepSound[128];
if ( m_Local.m_nStepside )
{
Q_snprintf( szStepSound, sizeof( szStepSound ), "%s.RunFootstepLeft", g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType] );
}
else
{
Q_snprintf( szStepSound, sizeof( szStepSound ), "%s.RunFootstepRight", g_ppszPlayerSoundPrefixNames[m_iPlayerSoundType] );
}
CSoundParameters params;
if ( GetParametersForSound( szStepSound, params, NULL ) == false )
return;
CRecipientFilter filter;
filter.AddRecipientsByPAS( vecOrigin );
#ifndef CLIENT_DLL
// im MP, server removed all players in origins PVS, these players
// generate the footsteps clientside
if ( gpGlobals->maxClients > 1 )
filter.RemoveRecipientsByPVS( vecOrigin );
#endif
EmitSound_t ep;
ep.m_nChannel = CHAN_BODY;
ep.m_pSoundName = params.soundname;
ep.m_flVolume = fvol;
ep.m_SoundLevel = params.soundlevel;
ep.m_nFlags = 0;
ep.m_nPitch = params.pitch;
ep.m_pOrigin = &vecOrigin;
EmitSound( filter, entindex(), ep );
}
//==========================
// ANIMATION CODE
//==========================
// Below this many degrees, slow down turning rate linearly
#define FADE_TURN_DEGREES 45.0f
// After this, need to start turning feet
#define MAX_TORSO_ANGLE 90.0f
// Below this amount, don't play a turning animation/perform IK
#define MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION 15.0f
static ConVar tf2_feetyawrunscale( "tf2_feetyawrunscale", "2", FCVAR_REPLICATED, "Multiplier on tf2_feetyawrate to allow turning faster when running." );
extern ConVar sv_backspeed;
extern ConVar mp_feetyawrate;
extern ConVar mp_facefronttime;
extern ConVar mp_ik;
CPlayerAnimState::CPlayerAnimState( CHL2MP_Player *outer )
: m_pOuter( outer )
{
m_flGaitYaw = 0.0f;
m_flGoalFeetYaw = 0.0f;
m_flCurrentFeetYaw = 0.0f;
m_flCurrentTorsoYaw = 0.0f;
m_flLastYaw = 0.0f;
m_flLastTurnTime = 0.0f;
m_flTurnCorrectionTime = 0.0f;
};
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPlayerAnimState::Update()
{
m_angRender = GetOuter()->GetLocalAngles();
m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
ComputePoseParam_BodyYaw();
ComputePoseParam_BodyPitch(GetOuter()->GetModelPtr());
ComputePoseParam_BodyLookYaw();
ComputePlaybackRate();
#ifdef CLIENT_DLL
GetOuter()->UpdateLookAt();
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPlayerAnimState::ComputePlaybackRate()
{
// Determine ideal playback rate
Vector vel;
GetOuterAbsVelocity( vel );
float speed = vel.Length2D();
bool isMoving = ( speed > 0.5f ) ? true : false;
float maxspeed = GetOuter()->GetSequenceGroundSpeed( GetOuter()->GetSequence() );
if ( isMoving && ( maxspeed > 0.0f ) )
{
float flFactor = 1.0f;
// Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below
GetOuter()->SetPlaybackRate( ( speed * flFactor ) / maxspeed );
// BUG BUG:
// This stuff really should be m_flPlaybackRate = speed / m_flGroundSpeed
}
else
{
GetOuter()->SetPlaybackRate( 1.0f );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : CBasePlayer
//-----------------------------------------------------------------------------
CHL2MP_Player *CPlayerAnimState::GetOuter()
{
return m_pOuter;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : dt -
//-----------------------------------------------------------------------------
void CPlayerAnimState::EstimateYaw( void )
{
float dt = gpGlobals->frametime;
if ( !dt )
{
return;
}
Vector est_velocity;
QAngle angles;
GetOuterAbsVelocity( est_velocity );
angles = GetOuter()->GetLocalAngles();
if ( est_velocity[1] == 0 && est_velocity[0] == 0 )
{
float flYawDiff = angles[YAW] - m_flGaitYaw;
flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360;
if (flYawDiff > 180)
flYawDiff -= 360;
if (flYawDiff < -180)
flYawDiff += 360;
if (dt < 0.25)
flYawDiff *= dt * 4;
else
flYawDiff *= dt;
m_flGaitYaw += flYawDiff;
m_flGaitYaw = m_flGaitYaw - (int)(m_flGaitYaw / 360) * 360;
}
else
{
m_flGaitYaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI);
if (m_flGaitYaw > 180)
m_flGaitYaw = 180;
else if (m_flGaitYaw < -180)
m_flGaitYaw = -180;
}
}
//-----------------------------------------------------------------------------
// Purpose: Override for backpeddling
// Input : dt -
//-----------------------------------------------------------------------------
void CPlayerAnimState::ComputePoseParam_BodyYaw( void )
{
int iYaw = GetOuter()->LookupPoseParameter( "move_yaw" );
if ( iYaw < 0 )
return;
// view direction relative to movement
float flYaw;
EstimateYaw();
QAngle angles = GetOuter()->GetLocalAngles();
float ang = angles[ YAW ];
if ( ang > 180.0f )
{
ang -= 360.0f;
}
else if ( ang < -180.0f )
{
ang += 360.0f;
}
// calc side to side turning
flYaw = ang - m_flGaitYaw;
// Invert for mapping into 8way blend
flYaw = -flYaw;
flYaw = flYaw - (int)(flYaw / 360) * 360;
if (flYaw < -180)
{
flYaw = flYaw + 360;
}
else if (flYaw > 180)
{
flYaw = flYaw - 360;
}
GetOuter()->SetPoseParameter( iYaw, flYaw );
#ifndef CLIENT_DLL
//Adrian: Make the model's angle match the legs so the hitboxes match on both sides.
GetOuter()->SetLocalAngles( QAngle( GetOuter()->GetAnimEyeAngles().x, m_flCurrentFeetYaw, 0 ) );
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPlayerAnimState::ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr )
{
// Get pitch from v_angle
float flPitch = GetOuter()->GetLocalAngles()[ PITCH ];
if ( flPitch > 180.0f )
{
flPitch -= 360.0f;
}
flPitch = clamp( flPitch, -90, 90 );
QAngle absangles = GetOuter()->GetAbsAngles();
absangles.x = 0.0f;
m_angRender = absangles;
m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
// See if we have a blender for pitch
GetOuter()->SetPoseParameter( pStudioHdr, "aim_pitch", flPitch );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : goal -
// maxrate -
// dt -
// current -
// Output : int
//-----------------------------------------------------------------------------
int CPlayerAnimState::ConvergeAngles( float goal,float maxrate, float dt, float& current )
{
int direction = TURN_NONE;
float anglediff = goal - current;
float anglediffabs = fabs( anglediff );
anglediff = AngleNormalize( anglediff );
float scale = 1.0f;
if ( anglediffabs <= FADE_TURN_DEGREES )
{
scale = anglediffabs / FADE_TURN_DEGREES;
// Always do at least a bit of the turn ( 1% )
scale = clamp( scale, 0.01f, 1.0f );
}
float maxmove = maxrate * dt * scale;
if ( fabs( anglediff ) < maxmove )
{
current = goal;
}
else
{
if ( anglediff > 0 )
{
current += maxmove;
direction = TURN_LEFT;
}
else
{
current -= maxmove;
direction = TURN_RIGHT;
}
}
current = AngleNormalize( current );
return direction;
}
void CPlayerAnimState::ComputePoseParam_BodyLookYaw( void )
{
QAngle absangles = GetOuter()->GetAbsAngles();
absangles.y = AngleNormalize( absangles.y );
m_angRender = absangles;
m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
// See if we even have a blender for pitch
int upper_body_yaw = GetOuter()->LookupPoseParameter( "aim_yaw" );
if ( upper_body_yaw < 0 )
{
return;
}
// Assume upper and lower bodies are aligned and that we're not turning
float flGoalTorsoYaw = 0.0f;
int turning = TURN_NONE;
float turnrate = 360.0f;
Vector vel;
GetOuterAbsVelocity( vel );
bool isMoving = ( vel.Length() > 1.0f ) ? true : false;
if ( !isMoving )
{
// Just stopped moving, try and clamp feet
if ( m_flLastTurnTime <= 0.0f )
{
m_flLastTurnTime = gpGlobals->curtime;
m_flLastYaw = GetOuter()->GetAnimEyeAngles().y;
// Snap feet to be perfectly aligned with torso/eyes
m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y;
m_flCurrentFeetYaw = m_flGoalFeetYaw;
m_nTurningInPlace = TURN_NONE;
}
// If rotating in place, update stasis timer
if ( m_flLastYaw != GetOuter()->GetAnimEyeAngles().y )
{
m_flLastTurnTime = gpGlobals->curtime;
m_flLastYaw = GetOuter()->GetAnimEyeAngles().y;
}
if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
{
m_flLastTurnTime = gpGlobals->curtime;
}
turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );
QAngle eyeAngles = GetOuter()->GetAnimEyeAngles();
QAngle vAngle = GetOuter()->GetLocalAngles();
// See how far off current feetyaw is from true yaw
float yawdelta = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;
yawdelta = AngleNormalize( yawdelta );
bool rotated_too_far = false;
float yawmagnitude = fabs( yawdelta );
// If too far, then need to turn in place
if ( yawmagnitude > 45 )
{
rotated_too_far = true;
}
// Standing still for a while, rotate feet around to face forward
// Or rotated too far
// FIXME: Play an in place turning animation
if ( rotated_too_far ||
( gpGlobals->curtime > m_flLastTurnTime + mp_facefronttime.GetFloat() ) )
{
m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y;
m_flLastTurnTime = gpGlobals->curtime;
/* float yd = m_flCurrentFeetYaw - m_flGoalFeetYaw;
if ( yd > 0 )
{
m_nTurningInPlace = TURN_RIGHT;
}
else if ( yd < 0 )
{
m_nTurningInPlace = TURN_LEFT;
}
else
{
m_nTurningInPlace = TURN_NONE;
}
turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );
yawdelta = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;*/
}
// Snap upper body into position since the delta is already smoothed for the feet
flGoalTorsoYaw = yawdelta;
m_flCurrentTorsoYaw = flGoalTorsoYaw;
}
else
{
m_flLastTurnTime = 0.0f;
m_nTurningInPlace = TURN_NONE;
m_flCurrentFeetYaw = m_flGoalFeetYaw = GetOuter()->GetAnimEyeAngles().y;
flGoalTorsoYaw = 0.0f;
m_flCurrentTorsoYaw = GetOuter()->GetAnimEyeAngles().y - m_flCurrentFeetYaw;
}
if ( turning == TURN_NONE )
{
m_nTurningInPlace = turning;
}
if ( m_nTurningInPlace != TURN_NONE )
{
// If we're close to finishing the turn, then turn off the turning animation
if ( fabs( m_flCurrentFeetYaw - m_flGoalFeetYaw ) < MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION )
{
m_nTurningInPlace = TURN_NONE;
}
}
// Rotate entire body into position
absangles = GetOuter()->GetAbsAngles();
absangles.y = m_flCurrentFeetYaw;
m_angRender = absangles;
m_angRender[ PITCH ] = m_angRender[ ROLL ] = 0.0f;
GetOuter()->SetPoseParameter( upper_body_yaw, clamp( m_flCurrentTorsoYaw, -60.0f, 60.0f ) );
/*
// FIXME: Adrian, what is this?
int body_yaw = GetOuter()->LookupPoseParameter( "body_yaw" );
if ( body_yaw >= 0 )
{
GetOuter()->SetPoseParameter( body_yaw, 30 );
}
*/
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : activity -
// Output : Activity
//-----------------------------------------------------------------------------
Activity CPlayerAnimState::BodyYawTranslateActivity( Activity activity )
{
// Not even standing still, sigh
if ( activity != ACT_IDLE )
return activity;
// Not turning
switch ( m_nTurningInPlace )
{
default:
case TURN_NONE:
return activity;
/*
case TURN_RIGHT:
return ACT_TURNRIGHT45;
case TURN_LEFT:
return ACT_TURNLEFT45;
*/
case TURN_RIGHT:
case TURN_LEFT:
return mp_ik.GetBool() ? ACT_TURN : activity;
}
Assert( 0 );
return activity;
}
const QAngle& CPlayerAnimState::GetRenderAngles()
{
return m_angRender;
}
void CPlayerAnimState::GetOuterAbsVelocity( Vector& vel )
{
#if defined( CLIENT_DLL )
GetOuter()->EstimateAbsVelocity( vel );
#else
vel = GetOuter()->GetAbsVelocity();
#endif
}

View File

@ -1,97 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef HL2MP_PLAYER_SHARED_H
#define HL2MP_PLAYER_SHARED_H
#pragma once
#define HL2MP_PUSHAWAY_THINK_INTERVAL (1.0f / 20.0f)
#include "studio.h"
enum
{
PLAYER_SOUNDS_CITIZEN = 0,
PLAYER_SOUNDS_COMBINESOLDIER,
PLAYER_SOUNDS_METROPOLICE,
PLAYER_SOUNDS_MAX,
};
enum HL2MPPlayerState
{
// Happily running around in the game.
STATE_ACTIVE=0,
STATE_OBSERVER_MODE, // Noclipping around, watching players, etc.
NUM_PLAYER_STATES
};
#if defined( CLIENT_DLL )
#define CHL2MP_Player C_HL2MP_Player
#endif
class CPlayerAnimState
{
public:
enum
{
TURN_NONE = 0,
TURN_LEFT,
TURN_RIGHT
};
CPlayerAnimState( CHL2MP_Player *outer );
Activity BodyYawTranslateActivity( Activity activity );
void Update();
const QAngle& GetRenderAngles();
void GetPoseParameters( CStudioHdr *pStudioHdr, float poseParameter[MAXSTUDIOPOSEPARAM] );
CHL2MP_Player *GetOuter();
private:
void GetOuterAbsVelocity( Vector& vel );
int ConvergeAngles( float goal,float maxrate, float dt, float& current );
void EstimateYaw( void );
void ComputePoseParam_BodyYaw( void );
void ComputePoseParam_BodyPitch( CStudioHdr *pStudioHdr );
void ComputePoseParam_BodyLookYaw( void );
void ComputePlaybackRate();
CHL2MP_Player *m_pOuter;
float m_flGaitYaw;
float m_flStoredCycle;
// The following variables are used for tweaking the yaw of the upper body when standing still and
// making sure that it smoothly blends in and out once the player starts moving
// Direction feet were facing when we stopped moving
float m_flGoalFeetYaw;
float m_flCurrentFeetYaw;
float m_flCurrentTorsoYaw;
// To check if they are rotating in place
float m_flLastYaw;
// Time when we stopped moving
float m_flLastTurnTime;
// One of the above enums
int m_nTurningInPlace;
QAngle m_angRender;
float m_flTurnCorrectionTime;
};
#endif //HL2MP_PLAYER_SHARED_h

View File

@ -1,32 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include <KeyValues.h>
#include "hl2mp_weapon_parse.h"
#include "ammodef.h"
FileWeaponInfo_t* CreateWeaponInfo()
{
return new CHL2MPSWeaponInfo;
}
CHL2MPSWeaponInfo::CHL2MPSWeaponInfo()
{
m_iPlayerDamage = 0;
}
void CHL2MPSWeaponInfo::Parse( KeyValues *pKeyValuesData, const char *szWeaponName )
{
BaseClass::Parse( pKeyValuesData, szWeaponName );
m_iPlayerDamage = pKeyValuesData->GetInt( "damage", 0 );
}

View File

@ -1,35 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef HL2MP_WEAPON_PARSE_H
#define HL2MP_WEAPON_PARSE_H
#ifdef _WIN32
#pragma once
#endif
#include "weapon_parse.h"
#include "networkvar.h"
//--------------------------------------------------------------------------------------------------------
class CHL2MPSWeaponInfo : public FileWeaponInfo_t
{
public:
DECLARE_CLASS_GAMEROOT( CHL2MPSWeaponInfo, FileWeaponInfo_t );
CHL2MPSWeaponInfo();
virtual void Parse( ::KeyValues *pKeyValuesData, const char *szWeaponName );
public:
int m_iPlayerDamage;
};
#endif // HL2MP_WEAPON_PARSE_H

View File

@ -1,154 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "npcevent.h"
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#else
#include "hl2mp_player.h"
#endif
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#ifdef CLIENT_DLL
#define CWeapon357 C_Weapon357
#endif
//-----------------------------------------------------------------------------
// CWeapon357
//-----------------------------------------------------------------------------
class CWeapon357 : public CBaseHL2MPCombatWeapon
{
DECLARE_CLASS( CWeapon357, CBaseHL2MPCombatWeapon );
public:
CWeapon357( void );
void PrimaryAttack( void );
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
private:
CWeapon357( const CWeapon357 & );
};
IMPLEMENT_NETWORKCLASS_ALIASED( Weapon357, DT_Weapon357 )
BEGIN_NETWORK_TABLE( CWeapon357, DT_Weapon357 )
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CWeapon357 )
END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_357, CWeapon357 );
PRECACHE_WEAPON_REGISTER( weapon_357 );
#ifndef CLIENT_DLL
acttable_t CWeapon357::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false },
};
IMPLEMENT_ACTTABLE( CWeapon357 );
#endif
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CWeapon357::CWeapon357( void )
{
m_bReloadsSingly = false;
m_bFiresUnderwater = false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeapon357::PrimaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if ( !pPlayer )
{
return;
}
if ( m_iClip1 <= 0 )
{
if ( !m_bFireOnEmpty )
{
Reload();
}
else
{
WeaponSound( EMPTY );
m_flNextPrimaryAttack = 0.15;
}
return;
}
WeaponSound( SINGLE );
pPlayer->DoMuzzleFlash();
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
pPlayer->SetAnimation( PLAYER_ATTACK1 );
m_flNextPrimaryAttack = gpGlobals->curtime + 0.75;
m_flNextSecondaryAttack = gpGlobals->curtime + 0.75;
m_iClip1--;
Vector vecSrc = pPlayer->Weapon_ShootPosition();
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
FireBulletsInfo_t info( 1, vecSrc, vecAiming, vec3_origin, MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
info.m_pAttacker = pPlayer;
// Fire the bullets, and force the first shot to be perfectly accuracy
pPlayer->FireBullets( info );
//Disorient the player
QAngle angles = pPlayer->GetLocalAngles();
angles.x += random->RandomInt( -1, 1 );
angles.y += random->RandomInt( -1, 1 );
angles.z = 0;
#ifndef CLIENT_DLL
pPlayer->SnapEyeAngles( angles );
#endif
pPlayer->ViewPunch( QAngle( -8, random->RandomFloat( -2, 2 ), 0 ) );
if ( !m_iClip1 && pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
{
// HEV suit - indicate out of ammo condition
pPlayer->SetSuitUpdate( "!HEV_AMO0", FALSE, 0 );
}
}

View File

@ -1,312 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "npcevent.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "c_te_effect_dispatch.h"
#else
#include "hl2mp_player.h"
#include "te_effect_dispatch.h"
#include "prop_combine_ball.h"
#endif
#include "weapon_ar2.h"
#include "effect_dispatch_data.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#ifndef CLIENT_DLL
ConVar sk_weapon_ar2_alt_fire_radius( "sk_weapon_ar2_alt_fire_radius", "10" );
ConVar sk_weapon_ar2_alt_fire_duration( "sk_weapon_ar2_alt_fire_duration", "4" );
ConVar sk_weapon_ar2_alt_fire_mass( "sk_weapon_ar2_alt_fire_mass", "150" );
#endif
//=========================================================
//=========================================================
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponAR2, DT_WeaponAR2 )
BEGIN_NETWORK_TABLE( CWeaponAR2, DT_WeaponAR2 )
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CWeaponAR2 )
END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_ar2, CWeaponAR2 );
PRECACHE_WEAPON_REGISTER(weapon_ar2);
#ifndef CLIENT_DLL
acttable_t CWeaponAR2::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_AR2, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_AR2, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_AR2, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_AR2, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_AR2, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_AR2, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_AR2, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_AR2, false },
};
IMPLEMENT_ACTTABLE(CWeaponAR2);
#endif
CWeaponAR2::CWeaponAR2( )
{
m_fMinRange1 = 65;
m_fMaxRange1 = 2048;
m_fMinRange2 = 256;
m_fMaxRange2 = 1024;
m_nShotsFired = 0;
m_nVentPose = -1;
}
void CWeaponAR2::Precache( void )
{
BaseClass::Precache();
#ifndef CLIENT_DLL
UTIL_PrecacheOther( "prop_combine_ball" );
UTIL_PrecacheOther( "env_entity_dissolver" );
#endif
}
//-----------------------------------------------------------------------------
// Purpose: Handle grenade detonate in-air (even when no ammo is left)
//-----------------------------------------------------------------------------
void CWeaponAR2::ItemPostFrame( void )
{
// See if we need to fire off our secondary round
if ( m_bShotDelayed && gpGlobals->curtime > m_flDelayedFire )
{
DelayedAttack();
}
// Update our pose parameter for the vents
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner )
{
CBaseViewModel *pVM = pOwner->GetViewModel();
if ( pVM )
{
if ( m_nVentPose == -1 )
{
m_nVentPose = pVM->LookupPoseParameter( "VentPoses" );
}
float flVentPose = RemapValClamped( m_nShotsFired, 0, 5, 0.0f, 1.0f );
pVM->SetPoseParameter( m_nVentPose, flVentPose );
}
}
BaseClass::ItemPostFrame();
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Activity
//-----------------------------------------------------------------------------
Activity CWeaponAR2::GetPrimaryAttackActivity( void )
{
if ( m_nShotsFired < 2 )
return ACT_VM_PRIMARYATTACK;
if ( m_nShotsFired < 3 )
return ACT_VM_RECOIL1;
if ( m_nShotsFired < 4 )
return ACT_VM_RECOIL2;
return ACT_VM_RECOIL3;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &tr -
// nDamageType -
//-----------------------------------------------------------------------------
void CWeaponAR2::DoImpactEffect( trace_t &tr, int nDamageType )
{
CEffectData data;
data.m_vOrigin = tr.endpos + ( tr.plane.normal * 1.0f );
data.m_vNormal = tr.plane.normal;
DispatchEffect( "AR2Impact", data );
BaseClass::DoImpactEffect( tr, nDamageType );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponAR2::DelayedAttack( void )
{
m_bShotDelayed = false;
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
// Deplete the clip completely
SendWeaponAnim( ACT_VM_SECONDARYATTACK );
m_flNextSecondaryAttack = pOwner->m_flNextAttack = gpGlobals->curtime + SequenceDuration();
// Register a muzzleflash for the AI
pOwner->DoMuzzleFlash();
WeaponSound( WPN_DOUBLE );
// Fire the bullets
Vector vecSrc = pOwner->Weapon_ShootPosition( );
Vector vecAiming = pOwner->GetAutoaimVector( AUTOAIM_2DEGREES );
Vector impactPoint = vecSrc + ( vecAiming * MAX_TRACE_LENGTH );
// Fire the bullets
Vector vecVelocity = vecAiming * 1000.0f;
#ifndef CLIENT_DLL
// Fire the combine ball
CreateCombineBall( vecSrc,
vecVelocity,
sk_weapon_ar2_alt_fire_radius.GetFloat(),
sk_weapon_ar2_alt_fire_mass.GetFloat(),
sk_weapon_ar2_alt_fire_duration.GetFloat(),
pOwner );
// View effects
color32 white = {255, 255, 255, 64};
UTIL_ScreenFade( pOwner, white, 0.1, 0, FFADE_IN );
#endif
//Disorient the player
QAngle angles = pOwner->GetLocalAngles();
angles.x += random->RandomInt( -4, 4 );
angles.y += random->RandomInt( -4, 4 );
angles.z = 0;
// pOwner->SnapEyeAngles( angles );
pOwner->ViewPunch( QAngle( SharedRandomInt( "ar2pax", -8, -12 ), SharedRandomInt( "ar2pay", 1, 2 ), 0 ) );
// Decrease ammo
pOwner->RemoveAmmo( 1, m_iSecondaryAmmoType );
// Can shoot again immediately
m_flNextPrimaryAttack = gpGlobals->curtime + 0.5f;
// Can blow up after a short delay (so have time to release mouse button)
m_flNextSecondaryAttack = gpGlobals->curtime + 1.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponAR2::SecondaryAttack( void )
{
if ( m_bShotDelayed )
return;
// Cannot fire underwater
if ( GetOwner() && GetOwner()->GetWaterLevel() == 3 )
{
SendWeaponAnim( ACT_VM_DRYFIRE );
BaseClass::WeaponSound( EMPTY );
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f;
return;
}
m_bShotDelayed = true;
m_flNextPrimaryAttack = m_flNextSecondaryAttack = m_flDelayedFire = gpGlobals->curtime + 0.5f;
SendWeaponAnim( ACT_VM_FIDGET );
WeaponSound( SPECIAL1 );
}
//-----------------------------------------------------------------------------
// Purpose: Override if we're waiting to release a shot
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponAR2::CanHolster( void )
{
if ( m_bShotDelayed )
return false;
return BaseClass::CanHolster();
}
bool CWeaponAR2::Deploy( void )
{
m_bShotDelayed = false;
m_flDelayedFire = 0.0f;
return BaseClass::Deploy();
}
//-----------------------------------------------------------------------------
// Purpose: Override if we're waiting to release a shot
//-----------------------------------------------------------------------------
bool CWeaponAR2::Reload( void )
{
if ( m_bShotDelayed )
return false;
return BaseClass::Reload();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponAR2::AddViewKick( void )
{
#define EASY_DAMPEN 0.5f
#define MAX_VERTICAL_KICK 8.0f //Degrees
#define SLIDE_LIMIT 5.0f //Seconds
//Get the view kick
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if (!pPlayer)
return;
DoMachineGunKick( pPlayer, EASY_DAMPEN, MAX_VERTICAL_KICK, m_fFireDuration, SLIDE_LIMIT );
}
//-----------------------------------------------------------------------------
const WeaponProficiencyInfo_t *CWeaponAR2::GetProficiencyValues()
{
static WeaponProficiencyInfo_t proficiencyTable[] =
{
{ 7.0, 0.75 },
{ 5.00, 0.75 },
{ 3.0, 0.85 },
{ 5.0/3.0, 0.75 },
{ 1.00, 1.0 },
};
COMPILE_TIME_ASSERT( ARRAYSIZE(proficiencyTable) == WEAPON_PROFICIENCY_PERFECT + 1);
return proficiencyTable;
}

View File

@ -1,84 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Projectile shot from the AR2
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#ifndef WEAPONAR2_H
#define WEAPONAR2_H
#include "basegrenade_shared.h"
#include "weapon_hl2mpbase_machinegun.h"
#ifdef CLIENT_DLL
#define CWeaponAR2 C_WeaponAR2
#endif
class CWeaponAR2 : public CHL2MPMachineGun
{
public:
DECLARE_CLASS( CWeaponAR2, CHL2MPMachineGun );
CWeaponAR2();
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
void ItemPostFrame( void );
void Precache( void );
void SecondaryAttack( void );
void DelayedAttack( void );
const char *GetTracerType( void ) { return "AR2Tracer"; }
void AddViewKick( void );
int GetMinBurst( void ) { return 2; }
int GetMaxBurst( void ) { return 5; }
float GetFireRate( void ) { return 0.1f; }
bool CanHolster( void );
bool Reload( void );
Activity GetPrimaryAttackActivity( void );
void DoImpactEffect( trace_t &tr, int nDamageType );
virtual bool Deploy( void );
virtual const Vector& GetBulletSpread( void )
{
static Vector cone;
cone = VECTOR_CONE_3DEGREES;
return cone;
}
const WeaponProficiencyInfo_t *GetProficiencyValues();
private:
CWeaponAR2( const CWeaponAR2 & );
protected:
float m_flDelayedFire;
bool m_bShotDelayed;
int m_nVentPose;
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
};
#endif //WEAPONAR2_H

View File

@ -1,956 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "npcevent.h"
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "c_te_effect_dispatch.h"
#else
#include "hl2mp_player.h"
#include "te_effect_dispatch.h"
#include "IEffects.h"
#include "Sprite.h"
#include "SpriteTrail.h"
#include "beam_shared.h"
#endif
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#include "effect_dispatch_data.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//#define BOLT_MODEL "models/crossbow_bolt.mdl"
#define BOLT_MODEL "models/weapons/w_missile_closed.mdl"
#define BOLT_AIR_VELOCITY 3500
#define BOLT_WATER_VELOCITY 1500
#define BOLT_SKIN_NORMAL 0
#define BOLT_SKIN_GLOW 1
#ifndef CLIENT_DLL
extern ConVar sk_plr_dmg_crossbow;
extern ConVar sk_npc_dmg_crossbow;
void TE_StickyBolt( IRecipientFilter& filter, float delay, Vector vecDirection, const Vector *origin );
//-----------------------------------------------------------------------------
// Crossbow Bolt
//-----------------------------------------------------------------------------
class CCrossbowBolt : public CBaseCombatCharacter
{
DECLARE_CLASS( CCrossbowBolt, CBaseCombatCharacter );
public:
CCrossbowBolt() { };
~CCrossbowBolt();
Class_T Classify( void ) { return CLASS_NONE; }
public:
void Spawn( void );
void Precache( void );
void BubbleThink( void );
void BoltTouch( CBaseEntity *pOther );
bool CreateVPhysics( void );
unsigned int PhysicsSolidMaskForEntity() const;
static CCrossbowBolt *BoltCreate( const Vector &vecOrigin, const QAngle &angAngles, int iDamage, CBaseEntity *pentOwner = NULL );
protected:
bool CreateSprites( void );
CHandle<CSprite> m_pGlowSprite;
//CHandle<CSpriteTrail> m_pGlowTrail;
int m_iDamage;
DECLARE_DATADESC();
DECLARE_SERVERCLASS();
};
LINK_ENTITY_TO_CLASS( crossbow_bolt, CCrossbowBolt );
BEGIN_DATADESC( CCrossbowBolt )
// Function Pointers
DEFINE_FUNCTION( BubbleThink ),
DEFINE_FUNCTION( BoltTouch ),
// These are recreated on reload, they don't need storage
DEFINE_FIELD( m_pGlowSprite, FIELD_EHANDLE ),
//DEFINE_FIELD( m_pGlowTrail, FIELD_EHANDLE ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST( CCrossbowBolt, DT_CrossbowBolt )
END_SEND_TABLE()
CCrossbowBolt *CCrossbowBolt::BoltCreate(const Vector &vecOrigin, const QAngle &angAngles, int iDamage, CBaseEntity *pentOwner)
{
// Create a new entity with CCrossbowBolt private data
CCrossbowBolt *pBolt = (CCrossbowBolt *)CreateEntityByName( "crossbow_bolt" );
UTIL_SetOrigin( pBolt, vecOrigin );
pBolt->SetAbsAngles( angAngles );
pBolt->Spawn();
pBolt->SetOwnerEntity( pentOwner );
pBolt->m_iDamage = iDamage;
return pBolt;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CCrossbowBolt::~CCrossbowBolt( void )
{
if ( m_pGlowSprite )
{
UTIL_Remove( m_pGlowSprite );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CCrossbowBolt::CreateVPhysics( void )
{
// Create the object in the physics system
VPhysicsInitNormal( SOLID_BBOX, FSOLID_NOT_STANDABLE, false );
return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
unsigned int CCrossbowBolt::PhysicsSolidMaskForEntity() const
{
return ( BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_HITBOX ) & ~CONTENTS_GRATE;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CCrossbowBolt::CreateSprites( void )
{
// Start up the eye glow
m_pGlowSprite = CSprite::SpriteCreate( "sprites/light_glow02_noz.vmt", GetLocalOrigin(), false );
if ( m_pGlowSprite != NULL )
{
m_pGlowSprite->FollowEntity( this );
m_pGlowSprite->SetTransparency( kRenderGlow, 255, 255, 255, 128, kRenderFxNoDissipation );
m_pGlowSprite->SetScale( 0.2f );
m_pGlowSprite->TurnOff();
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCrossbowBolt::Spawn( void )
{
Precache( );
SetModel( "models/crossbow_bolt.mdl" );
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_CUSTOM );
UTIL_SetSize( this, -Vector(1,1,1), Vector(1,1,1) );
SetSolid( SOLID_BBOX );
SetGravity( 0.05f );
// Make sure we're updated if we're underwater
UpdateWaterState();
SetTouch( &CCrossbowBolt::BoltTouch );
SetThink( &CCrossbowBolt::BubbleThink );
SetNextThink( gpGlobals->curtime + 0.1f );
CreateSprites();
// Make us glow until we've hit the wall
m_nSkin = BOLT_SKIN_GLOW;
}
void CCrossbowBolt::Precache( void )
{
PrecacheModel( BOLT_MODEL );
// This is used by C_TEStickyBolt, despte being different from above!!!
PrecacheModel( "models/crossbow_bolt.mdl" );
PrecacheModel( "sprites/light_glow02_noz.vmt" );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pOther -
//-----------------------------------------------------------------------------
void CCrossbowBolt::BoltTouch( CBaseEntity *pOther )
{
if ( !pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS) )
return;
if ( pOther->m_takedamage != DAMAGE_NO )
{
trace_t tr, tr2;
tr = BaseClass::GetTouchTrace();
Vector vecNormalizedVel = GetAbsVelocity();
ClearMultiDamage();
VectorNormalize( vecNormalizedVel );
if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->IsNPC() )
{
CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), m_iDamage, DMG_NEVERGIB );
dmgInfo.AdjustPlayerDamageInflictedForSkillLevel();
CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f );
dmgInfo.SetDamagePosition( tr.endpos );
pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr );
}
else
{
CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), m_iDamage, DMG_BULLET | DMG_NEVERGIB );
CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f );
dmgInfo.SetDamagePosition( tr.endpos );
pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr );
}
ApplyMultiDamage();
//Adrian: keep going through the glass.
if ( pOther->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS )
return;
SetAbsVelocity( Vector( 0, 0, 0 ) );
// play body "thwack" sound
EmitSound( "Weapon_Crossbow.BoltHitBody" );
Vector vForward;
AngleVectors( GetAbsAngles(), &vForward );
VectorNormalize ( vForward );
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vForward * 128, MASK_OPAQUE, pOther, COLLISION_GROUP_NONE, &tr2 );
if ( tr2.fraction != 1.0f )
{
// NDebugOverlay::Box( tr2.endpos, Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 255, 0, 0, 10 );
// NDebugOverlay::Box( GetAbsOrigin(), Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 0, 255, 0, 10 );
if ( tr2.m_pEnt == NULL || ( tr2.m_pEnt && tr2.m_pEnt->GetMoveType() == MOVETYPE_NONE ) )
{
CEffectData data;
data.m_vOrigin = tr2.endpos;
data.m_vNormal = vForward;
data.m_nEntIndex = tr2.fraction != 1.0f;
DispatchEffect( "BoltImpact", data );
}
}
SetTouch( NULL );
SetThink( NULL );
UTIL_Remove( this );
}
else
{
trace_t tr;
tr = BaseClass::GetTouchTrace();
// See if we struck the world
if ( pOther->GetMoveType() == MOVETYPE_NONE && !( tr.surface.flags & SURF_SKY ) )
{
EmitSound( "Weapon_Crossbow.BoltHitWorld" );
// if what we hit is static architecture, can stay around for a while.
Vector vecDir = GetAbsVelocity();
float speed = VectorNormalize( vecDir );
// See if we should reflect off this surface
float hitDot = DotProduct( tr.plane.normal, -vecDir );
if ( ( hitDot < 0.5f ) && ( speed > 100 ) )
{
Vector vReflection = 2.0f * tr.plane.normal * hitDot + vecDir;
QAngle reflectAngles;
VectorAngles( vReflection, reflectAngles );
SetLocalAngles( reflectAngles );
SetAbsVelocity( vReflection * speed * 0.75f );
// Start to sink faster
SetGravity( 1.0f );
}
else
{
SetThink( &CCrossbowBolt::SUB_Remove );
SetNextThink( gpGlobals->curtime + 2.0f );
//FIXME: We actually want to stick (with hierarchy) to what we've hit
SetMoveType( MOVETYPE_NONE );
Vector vForward;
AngleVectors( GetAbsAngles(), &vForward );
VectorNormalize ( vForward );
CEffectData data;
data.m_vOrigin = tr.endpos;
data.m_vNormal = vForward;
data.m_nEntIndex = 0;
DispatchEffect( "BoltImpact", data );
UTIL_ImpactTrace( &tr, DMG_BULLET );
AddEffects( EF_NODRAW );
SetTouch( NULL );
SetThink( &CCrossbowBolt::SUB_Remove );
SetNextThink( gpGlobals->curtime + 2.0f );
if ( m_pGlowSprite != NULL )
{
m_pGlowSprite->TurnOn();
m_pGlowSprite->FadeAndDie( 3.0f );
}
}
// Shoot some sparks
if ( UTIL_PointContents( GetAbsOrigin() ) != CONTENTS_WATER)
{
g_pEffects->Sparks( GetAbsOrigin() );
}
}
else
{
// Put a mark unless we've hit the sky
if ( ( tr.surface.flags & SURF_SKY ) == false )
{
UTIL_ImpactTrace( &tr, DMG_BULLET );
}
UTIL_Remove( this );
}
}
if ( g_pGameRules->IsMultiplayer() )
{
// SetThink( &CCrossbowBolt::ExplodeThink );
// SetNextThink( gpGlobals->curtime + 0.1f );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CCrossbowBolt::BubbleThink( void )
{
QAngle angNewAngles;
VectorAngles( GetAbsVelocity(), angNewAngles );
SetAbsAngles( angNewAngles );
SetNextThink( gpGlobals->curtime + 0.1f );
if ( GetWaterLevel() == 0 )
return;
UTIL_BubbleTrail( GetAbsOrigin() - GetAbsVelocity() * 0.1f, GetAbsOrigin(), 5 );
}
#endif
//-----------------------------------------------------------------------------
// CWeaponCrossbow
//-----------------------------------------------------------------------------
#ifdef CLIENT_DLL
#define CWeaponCrossbow C_WeaponCrossbow
#endif
class CWeaponCrossbow : public CBaseHL2MPCombatWeapon
{
DECLARE_CLASS( CWeaponCrossbow, CBaseHL2MPCombatWeapon );
public:
CWeaponCrossbow( void );
virtual void Precache( void );
virtual void PrimaryAttack( void );
virtual void SecondaryAttack( void );
virtual bool Deploy( void );
virtual bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
virtual bool Reload( void );
virtual void ItemPostFrame( void );
virtual void ItemBusyFrame( void );
virtual bool SendWeaponAnim( int iActivity );
#ifndef CLIENT_DLL
virtual void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
#endif
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
private:
void SetSkin( int skinNum );
void CheckZoomToggle( void );
void FireBolt( void );
void ToggleZoom( void );
// Various states for the crossbow's charger
enum ChargerState_t
{
CHARGER_STATE_START_LOAD,
CHARGER_STATE_START_CHARGE,
CHARGER_STATE_READY,
CHARGER_STATE_DISCHARGE,
CHARGER_STATE_OFF,
};
void CreateChargerEffects( void );
void SetChargerState( ChargerState_t state );
void DoLoadEffect( void );
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
private:
// Charger effects
ChargerState_t m_nChargeState;
#ifndef CLIENT_DLL
CHandle<CSprite> m_hChargerSprite;
#endif
CNetworkVar( bool, m_bInZoom );
CNetworkVar( bool, m_bMustReload );
CWeaponCrossbow( const CWeaponCrossbow & );
};
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponCrossbow, DT_WeaponCrossbow )
BEGIN_NETWORK_TABLE( CWeaponCrossbow, DT_WeaponCrossbow )
#ifdef CLIENT_DLL
RecvPropBool( RECVINFO( m_bInZoom ) ),
RecvPropBool( RECVINFO( m_bMustReload ) ),
#else
SendPropBool( SENDINFO( m_bInZoom ) ),
SendPropBool( SENDINFO( m_bMustReload ) ),
#endif
END_NETWORK_TABLE()
#ifdef CLIENT_DLL
BEGIN_PREDICTION_DATA( CWeaponCrossbow )
DEFINE_PRED_FIELD( m_bInZoom, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_bMustReload, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
END_PREDICTION_DATA()
#endif
LINK_ENTITY_TO_CLASS( weapon_crossbow, CWeaponCrossbow );
PRECACHE_WEAPON_REGISTER( weapon_crossbow );
#ifndef CLIENT_DLL
acttable_t CWeaponCrossbow::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_CROSSBOW, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_CROSSBOW, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_CROSSBOW, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_CROSSBOW, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_CROSSBOW, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_CROSSBOW, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_CROSSBOW, false },
};
IMPLEMENT_ACTTABLE(CWeaponCrossbow);
#endif
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CWeaponCrossbow::CWeaponCrossbow( void )
{
m_bReloadsSingly = true;
m_bFiresUnderwater = true;
m_bInZoom = false;
m_bMustReload = false;
}
#define CROSSBOW_GLOW_SPRITE "sprites/light_glow02_noz.vmt"
#define CROSSBOW_GLOW_SPRITE2 "sprites/blueflare1.vmt"
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrossbow::Precache( void )
{
#ifndef CLIENT_DLL
UTIL_PrecacheOther( "crossbow_bolt" );
#endif
PrecacheScriptSound( "Weapon_Crossbow.BoltHitBody" );
PrecacheScriptSound( "Weapon_Crossbow.BoltHitWorld" );
PrecacheScriptSound( "Weapon_Crossbow.BoltSkewer" );
PrecacheModel( CROSSBOW_GLOW_SPRITE );
PrecacheModel( CROSSBOW_GLOW_SPRITE2 );
BaseClass::Precache();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrossbow::PrimaryAttack( void )
{
if ( m_bInZoom && g_pGameRules->IsMultiplayer() )
{
// FireSniperBolt();
FireBolt();
}
else
{
FireBolt();
}
// Signal a reload
m_bMustReload = true;
SetWeaponIdleTime( gpGlobals->curtime + SequenceDuration( ACT_VM_PRIMARYATTACK ) );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrossbow::SecondaryAttack( void )
{
//NOTENOTE: The zooming is handled by the post/busy frames
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponCrossbow::Reload( void )
{
if ( BaseClass::Reload() )
{
m_bMustReload = false;
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrossbow::CheckZoomToggle( void )
{
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if ( pPlayer->m_afButtonPressed & IN_ATTACK2 )
{
ToggleZoom();
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrossbow::ItemBusyFrame( void )
{
// Allow zoom toggling even when we're reloading
CheckZoomToggle();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrossbow::ItemPostFrame( void )
{
// Allow zoom toggling
CheckZoomToggle();
if ( m_bMustReload && HasWeaponIdleTimeElapsed() )
{
Reload();
}
BaseClass::ItemPostFrame();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrossbow::FireBolt( void )
{
if ( m_iClip1 <= 0 )
{
if ( !m_bFireOnEmpty )
{
Reload();
}
else
{
WeaponSound( EMPTY );
m_flNextPrimaryAttack = 0.15;
}
return;
}
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
#ifndef CLIENT_DLL
Vector vecAiming = pOwner->GetAutoaimVector( 0 );
Vector vecSrc = pOwner->Weapon_ShootPosition();
QAngle angAiming;
VectorAngles( vecAiming, angAiming );
CCrossbowBolt *pBolt = CCrossbowBolt::BoltCreate( vecSrc, angAiming, GetHL2MPWpnData().m_iPlayerDamage, pOwner );
if ( pOwner->GetWaterLevel() == 3 )
{
pBolt->SetAbsVelocity( vecAiming * BOLT_WATER_VELOCITY );
}
else
{
pBolt->SetAbsVelocity( vecAiming * BOLT_AIR_VELOCITY );
}
#endif
m_iClip1--;
pOwner->ViewPunch( QAngle( -2, 0, 0 ) );
WeaponSound( SINGLE );
WeaponSound( SPECIAL2 );
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
if ( !m_iClip1 && pOwner->GetAmmoCount( m_iPrimaryAmmoType ) <= 0 )
{
// HEV suit - indicate out of ammo condition
pOwner->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
}
m_flNextPrimaryAttack = m_flNextSecondaryAttack = gpGlobals->curtime + 0.75;
DoLoadEffect();
SetChargerState( CHARGER_STATE_DISCHARGE );
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponCrossbow::Deploy( void )
{
if ( m_iClip1 <= 0 )
{
return DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_CROSSBOW_DRAW_UNLOADED, (char*)GetAnimPrefix() );
}
SetSkin( BOLT_SKIN_GLOW );
return BaseClass::Deploy();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pSwitchingTo -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponCrossbow::Holster( CBaseCombatWeapon *pSwitchingTo )
{
if ( m_bInZoom )
{
ToggleZoom();
}
SetChargerState( CHARGER_STATE_OFF );
return BaseClass::Holster( pSwitchingTo );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrossbow::ToggleZoom( void )
{
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if ( pPlayer == NULL )
return;
#ifndef CLIENT_DLL
if ( m_bInZoom )
{
if ( pPlayer->SetFOV( this, 0, 0.2f ) )
{
m_bInZoom = false;
}
}
else
{
if ( pPlayer->SetFOV( this, 20, 0.1f ) )
{
m_bInZoom = true;
}
}
#endif
}
#define BOLT_TIP_ATTACHMENT 2
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrossbow::CreateChargerEffects( void )
{
#ifndef CLIENT_DLL
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( m_hChargerSprite != NULL )
return;
m_hChargerSprite = CSprite::SpriteCreate( CROSSBOW_GLOW_SPRITE, GetAbsOrigin(), false );
if ( m_hChargerSprite )
{
m_hChargerSprite->SetAttachment( pOwner->GetViewModel(), BOLT_TIP_ATTACHMENT );
m_hChargerSprite->SetTransparency( kRenderTransAdd, 255, 128, 0, 255, kRenderFxNoDissipation );
m_hChargerSprite->SetBrightness( 0 );
m_hChargerSprite->SetScale( 0.1f );
m_hChargerSprite->TurnOff();
}
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : skinNum -
//-----------------------------------------------------------------------------
void CWeaponCrossbow::SetSkin( int skinNum )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
CBaseViewModel *pViewModel = pOwner->GetViewModel();
if ( pViewModel == NULL )
return;
pViewModel->m_nSkin = skinNum;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrossbow::DoLoadEffect( void )
{
SetSkin( BOLT_SKIN_GLOW );
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
CBaseViewModel *pViewModel = pOwner->GetViewModel();
if ( pViewModel == NULL )
return;
CEffectData data;
#ifdef CLIENT_DLL
data.m_hEntity = pViewModel->GetRefEHandle();
#else
data.m_nEntIndex = pViewModel->entindex();
#endif
data.m_nAttachmentIndex = 1;
DispatchEffect( "CrossbowLoad", data );
#ifndef CLIENT_DLL
CSprite *pBlast = CSprite::SpriteCreate( CROSSBOW_GLOW_SPRITE2, GetAbsOrigin(), false );
if ( pBlast )
{
pBlast->SetAttachment( pOwner->GetViewModel(), 1 );
pBlast->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNone );
pBlast->SetBrightness( 128 );
pBlast->SetScale( 0.2f );
pBlast->FadeOutFromSpawn();
}
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : state -
//-----------------------------------------------------------------------------
void CWeaponCrossbow::SetChargerState( ChargerState_t state )
{
// Make sure we're setup
CreateChargerEffects();
// Don't do this twice
if ( state == m_nChargeState )
return;
m_nChargeState = state;
switch( m_nChargeState )
{
case CHARGER_STATE_START_LOAD:
WeaponSound( SPECIAL1 );
// Shoot some sparks and draw a beam between the two outer points
DoLoadEffect();
break;
#ifndef CLIENT_DLL
case CHARGER_STATE_START_CHARGE:
{
if ( m_hChargerSprite == NULL )
break;
m_hChargerSprite->SetBrightness( 32, 0.5f );
m_hChargerSprite->SetScale( 0.025f, 0.5f );
m_hChargerSprite->TurnOn();
}
break;
case CHARGER_STATE_READY:
{
// Get fully charged
if ( m_hChargerSprite == NULL )
break;
m_hChargerSprite->SetBrightness( 80, 1.0f );
m_hChargerSprite->SetScale( 0.1f, 0.5f );
m_hChargerSprite->TurnOn();
}
break;
case CHARGER_STATE_DISCHARGE:
{
SetSkin( BOLT_SKIN_NORMAL );
if ( m_hChargerSprite == NULL )
break;
m_hChargerSprite->SetBrightness( 0 );
m_hChargerSprite->TurnOff();
}
break;
#endif
case CHARGER_STATE_OFF:
{
SetSkin( BOLT_SKIN_NORMAL );
#ifndef CLIENT_DLL
if ( m_hChargerSprite == NULL )
break;
m_hChargerSprite->SetBrightness( 0 );
m_hChargerSprite->TurnOff();
#endif
}
break;
default:
break;
}
}
#ifndef CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pEvent -
// *pOperator -
//-----------------------------------------------------------------------------
void CWeaponCrossbow::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
switch( pEvent->event )
{
case EVENT_WEAPON_THROW:
SetChargerState( CHARGER_STATE_START_LOAD );
break;
case EVENT_WEAPON_THROW2:
SetChargerState( CHARGER_STATE_START_CHARGE );
break;
case EVENT_WEAPON_THROW3:
SetChargerState( CHARGER_STATE_READY );
break;
default:
BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
break;
}
}
#endif
//-----------------------------------------------------------------------------
// Purpose: Set the desired activity for the weapon and its viewmodel counterpart
// Input : iActivity - activity to play
//-----------------------------------------------------------------------------
bool CWeaponCrossbow::SendWeaponAnim( int iActivity )
{
int newActivity = iActivity;
// The last shot needs a non-loaded activity
if ( ( newActivity == ACT_VM_IDLE ) && ( m_iClip1 <= 0 ) )
{
newActivity = ACT_VM_FIDGET;
}
//For now, just set the ideal activity and be done with it
return BaseClass::SendWeaponAnim( newActivity );
}

View File

@ -1,228 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Crowbar - an old favorite
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "hl2mp/weapon_crowbar.h"
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#include "gamerules.h"
#include "ammodef.h"
#include "mathlib/mathlib.h"
#include "in_buttons.h"
#include "vstdlib/random.h"
#include "npcevent.h"
#if defined( CLIENT_DLL )
#include "c_hl2mp_player.h"
#else
#include "hl2mp_player.h"
#include "ai_basenpc.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define CROWBAR_RANGE 75.0f
#define CROWBAR_REFIRE 0.4f
//-----------------------------------------------------------------------------
// CWeaponCrowbar
//-----------------------------------------------------------------------------
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponCrowbar, DT_WeaponCrowbar )
BEGIN_NETWORK_TABLE( CWeaponCrowbar, DT_WeaponCrowbar )
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CWeaponCrowbar )
END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_crowbar, CWeaponCrowbar );
PRECACHE_WEAPON_REGISTER( weapon_crowbar );
#ifndef CLIENT_DLL
acttable_t CWeaponCrowbar::m_acttable[] =
{
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true },
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false },
};
IMPLEMENT_ACTTABLE(CWeaponCrowbar);
#endif
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CWeaponCrowbar::CWeaponCrowbar( void )
{
}
//-----------------------------------------------------------------------------
// Purpose: Get the damage amount for the animation we're doing
// Input : hitActivity - currently played activity
// Output : Damage amount
//-----------------------------------------------------------------------------
float CWeaponCrowbar::GetDamageForActivity( Activity hitActivity )
{
return 25.0f;
}
//-----------------------------------------------------------------------------
// Purpose: Add in a view kick for this weapon
//-----------------------------------------------------------------------------
void CWeaponCrowbar::AddViewKick( void )
{
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if ( pPlayer == NULL )
return;
QAngle punchAng;
punchAng.x = SharedRandomFloat( "crowbarpax", 1.0f, 2.0f );
punchAng.y = SharedRandomFloat( "crowbarpay", -2.0f, -1.0f );
punchAng.z = 0.0f;
pPlayer->ViewPunch( punchAng );
}
#ifndef CLIENT_DLL
//-----------------------------------------------------------------------------
// Animation event handlers
//-----------------------------------------------------------------------------
void CWeaponCrowbar::HandleAnimEventMeleeHit( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
// Trace up or down based on where the enemy is...
// But only if we're basically facing that direction
Vector vecDirection;
AngleVectors( GetAbsAngles(), &vecDirection );
Vector vecEnd;
VectorMA( pOperator->Weapon_ShootPosition(), 50, vecDirection, vecEnd );
CBaseEntity *pHurt = pOperator->CheckTraceHullAttack( pOperator->Weapon_ShootPosition(), vecEnd,
Vector(-16,-16,-16), Vector(36,36,36), GetDamageForActivity( GetActivity() ), DMG_CLUB, 0.75 );
// did I hit someone?
if ( pHurt )
{
// play sound
WeaponSound( MELEE_HIT );
// Fake a trace impact, so the effects work out like a player's crowbaw
trace_t traceHit;
UTIL_TraceLine( pOperator->Weapon_ShootPosition(), pHurt->GetAbsOrigin(), MASK_SHOT_HULL, pOperator, COLLISION_GROUP_NONE, &traceHit );
ImpactEffect( traceHit );
}
else
{
WeaponSound( MELEE_MISS );
}
}
//-----------------------------------------------------------------------------
// Animation event
//-----------------------------------------------------------------------------
void CWeaponCrowbar::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
switch( pEvent->event )
{
case EVENT_WEAPON_MELEE_HIT:
HandleAnimEventMeleeHit( pEvent, pOperator );
break;
default:
BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
break;
}
}
//-----------------------------------------------------------------------------
// Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
//-----------------------------------------------------------------------------
ConVar sk_crowbar_lead_time( "sk_crowbar_lead_time", "0.9" );
int CWeaponCrowbar::WeaponMeleeAttack1Condition( float flDot, float flDist )
{
// Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer();
CBaseEntity *pEnemy = pNPC->GetEnemy();
if (!pEnemy)
return COND_NONE;
Vector vecVelocity;
vecVelocity = pEnemy->GetSmoothedVelocity( );
// Project where the enemy will be in a little while
float dt = sk_crowbar_lead_time.GetFloat();
dt += SharedRandomFloat( "crowbarmelee1", -0.3f, 0.2f );
if ( dt < 0.0f )
dt = 0.0f;
Vector vecExtrapolatedPos;
VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos );
Vector vecDelta;
VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta );
if ( fabs( vecDelta.z ) > 70 )
{
return COND_TOO_FAR_TO_ATTACK;
}
Vector vecForward = pNPC->BodyDirection2D( );
vecDelta.z = 0.0f;
float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() );
if ((flDist > 64) && (flExtrapolatedDist > 64))
{
return COND_TOO_FAR_TO_ATTACK;
}
float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() );
if ((flDot < 0.7) && (flExtrapolatedDot < 0.7))
{
return COND_NOT_FACING_ATTACK;
}
return COND_CAN_MELEE_ATTACK1;
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponCrowbar::Drop( const Vector &vecVelocity )
{
#ifndef CLIENT_DLL
UTIL_Remove( this );
#endif
}
float CWeaponCrowbar::GetRange( void )
{
return CROWBAR_RANGE;
}
float CWeaponCrowbar::GetFireRate( void )
{
return CROWBAR_REFIRE;
}

View File

@ -1,70 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#ifndef HL2MP_WEAPON_CROWBAR_H
#define HL2MP_WEAPON_CROWBAR_H
#pragma once
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#include "weapon_hl2mpbasebasebludgeon.h"
#ifdef CLIENT_DLL
#define CWeaponCrowbar C_WeaponCrowbar
#endif
//-----------------------------------------------------------------------------
// CWeaponCrowbar
//-----------------------------------------------------------------------------
class CWeaponCrowbar : public CBaseHL2MPBludgeonWeapon
{
public:
DECLARE_CLASS( CWeaponCrowbar, CBaseHL2MPBludgeonWeapon );
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
CWeaponCrowbar();
float GetRange( void );
float GetFireRate( void );
void AddViewKick( void );
float GetDamageForActivity( Activity hitActivity );
void SecondaryAttack( void ) { return; }
void Drop( const Vector &vecVelocity );
// Animation event
#ifndef CLIENT_DLL
virtual void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
void HandleAnimEventMeleeHit( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
int WeaponMeleeAttack1Condition( float flDot, float flDist );
#endif
CWeaponCrowbar( const CWeaponCrowbar & );
private:
};
#endif // HL2MP_WEAPON_CROWBAR_H

View File

@ -1,552 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "npcevent.h"
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#include "c_te_effect_dispatch.h"
#else
#include "hl2mp_player.h"
#include "te_effect_dispatch.h"
#include "grenade_frag.h"
#endif
#include "weapon_ar2.h"
#include "effect_dispatch_data.h"
#include "weapon_hl2mpbasehlmpcombatweapon.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define GRENADE_TIMER 2.5f //Seconds
#define GRENADE_PAUSED_NO 0
#define GRENADE_PAUSED_PRIMARY 1
#define GRENADE_PAUSED_SECONDARY 2
#define GRENADE_RADIUS 4.0f // inches
#define GRENADE_DAMAGE_RADIUS 250.0f
#ifdef CLIENT_DLL
#define CWeaponFrag C_WeaponFrag
#endif
//-----------------------------------------------------------------------------
// Fragmentation grenades
//-----------------------------------------------------------------------------
class CWeaponFrag: public CBaseHL2MPCombatWeapon
{
DECLARE_CLASS( CWeaponFrag, CBaseHL2MPCombatWeapon );
public:
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
CWeaponFrag();
void Precache( void );
void PrimaryAttack( void );
void SecondaryAttack( void );
void DecrementAmmo( CBaseCombatCharacter *pOwner );
void ItemPostFrame( void );
bool Deploy( void );
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
bool Reload( void );
#ifndef CLIENT_DLL
void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
#endif
void ThrowGrenade( CBasePlayer *pPlayer );
bool IsPrimed( bool ) { return ( m_AttackPaused != 0 ); }
private:
void RollGrenade( CBasePlayer *pPlayer );
void LobGrenade( CBasePlayer *pPlayer );
// check a throw from vecSrc. If not valid, move the position back along the line to vecEye
void CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc );
CNetworkVar( bool, m_bRedraw ); //Draw the weapon again after throwing a grenade
CNetworkVar( int, m_AttackPaused );
CNetworkVar( bool, m_fDrawbackFinished );
CWeaponFrag( const CWeaponFrag & );
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
};
#ifndef CLIENT_DLL
acttable_t CWeaponFrag::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_GRENADE, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_GRENADE, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_GRENADE, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_GRENADE, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_GRENADE, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_GRENADE, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_GRENADE, false },
};
IMPLEMENT_ACTTABLE(CWeaponFrag);
#endif
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponFrag, DT_WeaponFrag )
BEGIN_NETWORK_TABLE( CWeaponFrag, DT_WeaponFrag )
#ifdef CLIENT_DLL
RecvPropBool( RECVINFO( m_bRedraw ) ),
RecvPropBool( RECVINFO( m_fDrawbackFinished ) ),
RecvPropInt( RECVINFO( m_AttackPaused ) ),
#else
SendPropBool( SENDINFO( m_bRedraw ) ),
SendPropBool( SENDINFO( m_fDrawbackFinished ) ),
SendPropInt( SENDINFO( m_AttackPaused ) ),
#endif
END_NETWORK_TABLE()
#ifdef CLIENT_DLL
BEGIN_PREDICTION_DATA( CWeaponFrag )
DEFINE_PRED_FIELD( m_bRedraw, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_fDrawbackFinished, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_AttackPaused, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
END_PREDICTION_DATA()
#endif
LINK_ENTITY_TO_CLASS( weapon_frag, CWeaponFrag );
PRECACHE_WEAPON_REGISTER(weapon_frag);
CWeaponFrag::CWeaponFrag( void ) :
CBaseHL2MPCombatWeapon()
{
m_bRedraw = false;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponFrag::Precache( void )
{
BaseClass::Precache();
#ifndef CLIENT_DLL
UTIL_PrecacheOther( "npc_grenade_frag" );
#endif
PrecacheScriptSound( "WeaponFrag.Throw" );
PrecacheScriptSound( "WeaponFrag.Roll" );
}
#ifndef CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pEvent -
// *pOperator -
//-----------------------------------------------------------------------------
void CWeaponFrag::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
bool fThrewGrenade = false;
switch( pEvent->event )
{
case EVENT_WEAPON_SEQUENCE_FINISHED:
m_fDrawbackFinished = true;
break;
case EVENT_WEAPON_THROW:
ThrowGrenade( pOwner );
DecrementAmmo( pOwner );
fThrewGrenade = true;
break;
case EVENT_WEAPON_THROW2:
RollGrenade( pOwner );
DecrementAmmo( pOwner );
fThrewGrenade = true;
break;
case EVENT_WEAPON_THROW3:
LobGrenade( pOwner );
DecrementAmmo( pOwner );
fThrewGrenade = true;
break;
default:
BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
break;
}
#define RETHROW_DELAY 0.5
if( fThrewGrenade )
{
m_flNextPrimaryAttack = gpGlobals->curtime + RETHROW_DELAY;
m_flNextSecondaryAttack = gpGlobals->curtime + RETHROW_DELAY;
m_flTimeWeaponIdle = FLT_MAX; //NOTE: This is set once the animation has finished up!
}
}
#endif
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CWeaponFrag::Deploy( void )
{
m_bRedraw = false;
m_fDrawbackFinished = false;
return BaseClass::Deploy();
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponFrag::Holster( CBaseCombatWeapon *pSwitchingTo )
{
m_bRedraw = false;
m_fDrawbackFinished = false;
return BaseClass::Holster( pSwitchingTo );
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponFrag::Reload( void )
{
if ( !HasPrimaryAmmo() )
return false;
if ( ( m_bRedraw ) && ( m_flNextPrimaryAttack <= gpGlobals->curtime ) && ( m_flNextSecondaryAttack <= gpGlobals->curtime ) )
{
//Redraw the weapon
SendWeaponAnim( ACT_VM_DRAW );
//Update our times
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();
m_flTimeWeaponIdle = gpGlobals->curtime + SequenceDuration();
//Mark this as done
m_bRedraw = false;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponFrag::SecondaryAttack( void )
{
if ( m_bRedraw )
return;
if ( !HasPrimaryAmmo() )
return;
CBaseCombatCharacter *pOwner = GetOwner();
if ( pOwner == NULL )
return;
CBasePlayer *pPlayer = ToBasePlayer( pOwner );
if ( pPlayer == NULL )
return;
// Note that this is a secondary attack and prepare the grenade attack to pause.
m_AttackPaused = GRENADE_PAUSED_SECONDARY;
SendWeaponAnim( ACT_VM_PULLBACK_LOW );
// Don't let weapon idle interfere in the middle of a throw!
m_flTimeWeaponIdle = FLT_MAX;
m_flNextSecondaryAttack = FLT_MAX;
// If I'm now out of ammo, switch away
if ( !HasPrimaryAmmo() )
{
pPlayer->SwitchToNextBestWeapon( this );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponFrag::PrimaryAttack( void )
{
if ( m_bRedraw )
return;
CBaseCombatCharacter *pOwner = GetOwner();
if ( pOwner == NULL )
{
return;
}
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );;
if ( !pPlayer )
return;
// Note that this is a primary attack and prepare the grenade attack to pause.
m_AttackPaused = GRENADE_PAUSED_PRIMARY;
SendWeaponAnim( ACT_VM_PULLBACK_HIGH );
// Put both of these off indefinitely. We do not know how long
// the player will hold the grenade.
m_flTimeWeaponIdle = FLT_MAX;
m_flNextPrimaryAttack = FLT_MAX;
// If I'm now out of ammo, switch away
if ( !HasPrimaryAmmo() )
{
pPlayer->SwitchToNextBestWeapon( this );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pOwner -
//-----------------------------------------------------------------------------
void CWeaponFrag::DecrementAmmo( CBaseCombatCharacter *pOwner )
{
pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponFrag::ItemPostFrame( void )
{
if( m_fDrawbackFinished )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if (pOwner)
{
switch( m_AttackPaused )
{
case GRENADE_PAUSED_PRIMARY:
if( !(pOwner->m_nButtons & IN_ATTACK) )
{
SendWeaponAnim( ACT_VM_THROW );
m_fDrawbackFinished = false;
}
break;
case GRENADE_PAUSED_SECONDARY:
if( !(pOwner->m_nButtons & IN_ATTACK2) )
{
//See if we're ducking
if ( pOwner->m_nButtons & IN_DUCK )
{
//Send the weapon animation
SendWeaponAnim( ACT_VM_SECONDARYATTACK );
}
else
{
//Send the weapon animation
SendWeaponAnim( ACT_VM_HAULBACK );
}
m_fDrawbackFinished = false;
}
break;
default:
break;
}
}
}
BaseClass::ItemPostFrame();
if ( m_bRedraw )
{
if ( IsViewModelSequenceFinished() )
{
Reload();
}
}
}
// check a throw from vecSrc. If not valid, move the position back along the line to vecEye
void CWeaponFrag::CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc )
{
trace_t tr;
UTIL_TraceHull( vecEye, vecSrc, -Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2), Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2),
pPlayer->PhysicsSolidMaskForEntity(), pPlayer, pPlayer->GetCollisionGroup(), &tr );
if ( tr.DidHit() )
{
vecSrc = tr.endpos;
}
}
void DropPrimedFragGrenade( CHL2MP_Player *pPlayer, CBaseCombatWeapon *pGrenade )
{
CWeaponFrag *pWeaponFrag = dynamic_cast<CWeaponFrag*>( pGrenade );
if ( pWeaponFrag )
{
pWeaponFrag->ThrowGrenade( pPlayer );
pWeaponFrag->DecrementAmmo( pPlayer );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pPlayer -
//-----------------------------------------------------------------------------
void CWeaponFrag::ThrowGrenade( CBasePlayer *pPlayer )
{
#ifndef CLIENT_DLL
Vector vecEye = pPlayer->EyePosition();
Vector vForward, vRight;
pPlayer->EyeVectors( &vForward, &vRight, NULL );
Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f;
CheckThrowPosition( pPlayer, vecEye, vecSrc );
// vForward[0] += 0.1f;
vForward[2] += 0.1f;
Vector vecThrow;
pPlayer->GetVelocity( &vecThrow, NULL );
vecThrow += vForward * 1200;
CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(600,random->RandomInt(-1200,1200),0), pPlayer, GRENADE_TIMER, false );
if ( pGrenade )
{
if ( pPlayer && pPlayer->m_lifeState != LIFE_ALIVE )
{
pPlayer->GetVelocity( &vecThrow, NULL );
IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject();
if ( pPhysicsObject )
{
pPhysicsObject->SetVelocity( &vecThrow, NULL );
}
}
pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage );
pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS );
}
#endif
m_bRedraw = true;
WeaponSound( SINGLE );
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pPlayer -
//-----------------------------------------------------------------------------
void CWeaponFrag::LobGrenade( CBasePlayer *pPlayer )
{
#ifndef CLIENT_DLL
Vector vecEye = pPlayer->EyePosition();
Vector vForward, vRight;
pPlayer->EyeVectors( &vForward, &vRight, NULL );
Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f + Vector( 0, 0, -8 );
CheckThrowPosition( pPlayer, vecEye, vecSrc );
Vector vecThrow;
pPlayer->GetVelocity( &vecThrow, NULL );
vecThrow += vForward * 350 + Vector( 0, 0, 50 );
CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, vec3_angle, vecThrow, AngularImpulse(200,random->RandomInt(-600,600),0), pPlayer, GRENADE_TIMER, false );
if ( pGrenade )
{
pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage );
pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS );
}
#endif
WeaponSound( WPN_DOUBLE );
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
m_bRedraw = true;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pPlayer -
//-----------------------------------------------------------------------------
void CWeaponFrag::RollGrenade( CBasePlayer *pPlayer )
{
#ifndef CLIENT_DLL
// BUGBUG: Hardcoded grenade width of 4 - better not change the model :)
Vector vecSrc;
pPlayer->CollisionProp()->NormalizedToWorldSpace( Vector( 0.5f, 0.5f, 0.0f ), &vecSrc );
vecSrc.z += GRENADE_RADIUS;
Vector vecFacing = pPlayer->BodyDirection2D( );
// no up/down direction
vecFacing.z = 0;
VectorNormalize( vecFacing );
trace_t tr;
UTIL_TraceLine( vecSrc, vecSrc - Vector(0,0,16), MASK_PLAYERSOLID, pPlayer, COLLISION_GROUP_NONE, &tr );
if ( tr.fraction != 1.0 )
{
// compute forward vec parallel to floor plane and roll grenade along that
Vector tangent;
CrossProduct( vecFacing, tr.plane.normal, tangent );
CrossProduct( tr.plane.normal, tangent, vecFacing );
}
vecSrc += (vecFacing * 18.0);
CheckThrowPosition( pPlayer, pPlayer->WorldSpaceCenter(), vecSrc );
Vector vecThrow;
pPlayer->GetVelocity( &vecThrow, NULL );
vecThrow += vecFacing * 700;
// put it on its side
QAngle orientation(0,pPlayer->GetLocalAngles().y,-90);
// roll it
AngularImpulse rotSpeed(0,0,720);
CBaseGrenade *pGrenade = Fraggrenade_Create( vecSrc, orientation, vecThrow, rotSpeed, pPlayer, GRENADE_TIMER, false );
if ( pGrenade )
{
pGrenade->SetDamage( GetHL2MPWpnData().m_iPlayerDamage );
pGrenade->SetDamageRadius( GRENADE_DAMAGE_RADIUS );
}
#endif
WeaponSound( SPECIAL1 );
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
m_bRedraw = true;
}

View File

@ -1,330 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "in_buttons.h"
#include "takedamageinfo.h"
#include "ammodef.h"
#include "hl2mp_gamerules.h"
#ifdef CLIENT_DLL
extern IVModelInfoClient* modelinfo;
#else
extern IVModelInfo* modelinfo;
#endif
#if defined( CLIENT_DLL )
#include "vgui/ISurface.h"
#include "vgui_controls/Controls.h"
#include "c_hl2mp_player.h"
#include "hud_crosshair.h"
#else
#include "hl2mp_player.h"
#include "vphysics/constraints.h"
#endif
#include "weapon_hl2mpbase.h"
// ----------------------------------------------------------------------------- //
// Global functions.
// ----------------------------------------------------------------------------- //
bool IsAmmoType( int iAmmoType, const char *pAmmoName )
{
return GetAmmoDef()->Index( pAmmoName ) == iAmmoType;
}
static const char * s_WeaponAliasInfo[] =
{
"none", // WEAPON_NONE = 0,
//Melee
"shotgun", //WEAPON_AMERKNIFE,
NULL, // end of list marker
};
// ----------------------------------------------------------------------------- //
// CWeaponHL2MPBase tables.
// ----------------------------------------------------------------------------- //
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponHL2MPBase, DT_WeaponHL2MPBase )
BEGIN_NETWORK_TABLE( CWeaponHL2MPBase, DT_WeaponHL2MPBase )
#ifdef CLIENT_DLL
#else
// world weapon models have no aminations
// SendPropExclude( "DT_AnimTimeMustBeFirst", "m_flAnimTime" ),
// SendPropExclude( "DT_BaseAnimating", "m_nSequence" ),
// SendPropExclude( "DT_LocalActiveWeaponData", "m_flTimeWeaponIdle" ),
#endif
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CWeaponHL2MPBase )
END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_hl2mp_base, CWeaponHL2MPBase );
#ifdef GAME_DLL
BEGIN_DATADESC( CWeaponHL2MPBase )
END_DATADESC()
#endif
// ----------------------------------------------------------------------------- //
// CWeaponHL2MPBase implementation.
// ----------------------------------------------------------------------------- //
CWeaponHL2MPBase::CWeaponHL2MPBase()
{
SetPredictionEligible( true );
AddSolidFlags( FSOLID_TRIGGER ); // Nothing collides with these but it gets touches.
m_flNextResetCheckTime = 0.0f;
}
bool CWeaponHL2MPBase::IsPredicted() const
{
return true;
}
void CWeaponHL2MPBase::WeaponSound( WeaponSound_t sound_type, float soundtime /* = 0.0f */ )
{
#ifdef CLIENT_DLL
// If we have some sounds from the weapon classname.txt file, play a random one of them
const char *shootsound = GetWpnData().aShootSounds[ sound_type ];
if ( !shootsound || !shootsound[0] )
return;
CBroadcastRecipientFilter filter; // this is client side only
if ( !te->CanPredict() )
return;
CBaseEntity::EmitSound( filter, GetPlayerOwner()->entindex(), shootsound, &GetPlayerOwner()->GetAbsOrigin() );
#else
BaseClass::WeaponSound( sound_type, soundtime );
#endif
}
CBasePlayer* CWeaponHL2MPBase::GetPlayerOwner() const
{
return dynamic_cast< CBasePlayer* >( GetOwner() );
}
CHL2MP_Player* CWeaponHL2MPBase::GetHL2MPPlayerOwner() const
{
return dynamic_cast< CHL2MP_Player* >( GetOwner() );
}
#ifdef CLIENT_DLL
void CWeaponHL2MPBase::OnDataChanged( DataUpdateType_t type )
{
BaseClass::OnDataChanged( type );
if ( GetPredictable() && !ShouldPredict() )
ShutdownPredictable();
}
bool CWeaponHL2MPBase::ShouldPredict()
{
if ( GetOwner() && GetOwner() == C_BasePlayer::GetLocalPlayer() )
return true;
return BaseClass::ShouldPredict();
}
#else
void CWeaponHL2MPBase::Spawn()
{
BaseClass::Spawn();
// Set this here to allow players to shoot dropped weapons
SetCollisionGroup( COLLISION_GROUP_WEAPON );
}
void CWeaponHL2MPBase::Materialize( void )
{
if ( IsEffectActive( EF_NODRAW ) )
{
// changing from invisible state to visible.
EmitSound( "AlyxEmp.Charge" );
RemoveEffects( EF_NODRAW );
DoMuzzleFlash();
}
if ( HasSpawnFlags( SF_NORESPAWN ) == false )
{
VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false );
SetMoveType( MOVETYPE_VPHYSICS );
HL2MPRules()->AddLevelDesignerPlacedObject( this );
}
if ( HasSpawnFlags( SF_NORESPAWN ) == false )
{
if ( GetOriginalSpawnOrigin() == vec3_origin )
{
m_vOriginalSpawnOrigin = GetAbsOrigin();
m_vOriginalSpawnAngles = GetAbsAngles();
}
}
SetPickupTouch();
SetThink (NULL);
}
int CWeaponHL2MPBase::ObjectCaps()
{
return BaseClass::ObjectCaps() & ~FCAP_IMPULSE_USE;
}
#endif
void CWeaponHL2MPBase::FallInit( void )
{
#ifndef CLIENT_DLL
SetModel( GetWorldModel() );
VPhysicsDestroyObject();
if ( HasSpawnFlags( SF_NORESPAWN ) == false )
{
SetMoveType( MOVETYPE_NONE );
SetSolid( SOLID_BBOX );
AddSolidFlags( FSOLID_TRIGGER );
UTIL_DropToFloor( this, MASK_SOLID );
}
else
{
if ( !VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false ) )
{
SetMoveType( MOVETYPE_NONE );
SetSolid( SOLID_BBOX );
AddSolidFlags( FSOLID_TRIGGER );
}
else
{
#if !defined( CLIENT_DLL )
// Constrained start?
if ( HasSpawnFlags( SF_WEAPON_START_CONSTRAINED ) )
{
//Constrain the weapon in place
IPhysicsObject *pReferenceObject, *pAttachedObject;
pReferenceObject = g_PhysWorldObject;
pAttachedObject = VPhysicsGetObject();
if ( pReferenceObject && pAttachedObject )
{
constraint_fixedparams_t fixed;
fixed.Defaults();
fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject );
fixed.constraint.forceLimit = lbs2kg( 10000 );
fixed.constraint.torqueLimit = lbs2kg( 10000 );
IPhysicsConstraint *pConstraint = GetConstraint();
pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed );
pConstraint->SetGameData( (void *) this );
}
}
#endif //CLIENT_DLL
}
}
SetPickupTouch();
SetThink( &CBaseCombatWeapon::FallThink );
SetNextThink( gpGlobals->curtime + 0.1f );
#endif
}
const CHL2MPSWeaponInfo &CWeaponHL2MPBase::GetHL2MPWpnData() const
{
const FileWeaponInfo_t *pWeaponInfo = &GetWpnData();
const CHL2MPSWeaponInfo *pHL2MPInfo;
#ifdef _DEBUG
pHL2MPInfo = dynamic_cast< const CHL2MPSWeaponInfo* >( pWeaponInfo );
Assert( pHL2MPInfo );
#else
pHL2MPInfo = static_cast< const CHL2MPSWeaponInfo* >( pWeaponInfo );
#endif
return *pHL2MPInfo;
}
void CWeaponHL2MPBase::FireBullets( const FireBulletsInfo_t &info )
{
FireBulletsInfo_t modinfo = info;
modinfo.m_iPlayerDamage = GetHL2MPWpnData().m_iPlayerDamage;
BaseClass::FireBullets( modinfo );
}
#if defined( CLIENT_DLL )
#include "c_te_effect_dispatch.h"
#define NUM_MUZZLE_FLASH_TYPES 4
bool CWeaponHL2MPBase::OnFireEvent( C_BaseViewModel *pViewModel, const Vector& origin, const QAngle& angles, int event, const char *options )
{
return BaseClass::OnFireEvent( pViewModel, origin, angles, event, options );
}
void UTIL_ClipPunchAngleOffset( QAngle &in, const QAngle &punch, const QAngle &clip )
{
QAngle final = in + punch;
//Clip each component
for ( int i = 0; i < 3; i++ )
{
if ( final[i] > clip[i] )
{
final[i] = clip[i];
}
else if ( final[i] < -clip[i] )
{
final[i] = -clip[i];
}
//Return the result
in[i] = final[i] - punch[i];
}
}
#endif

View File

@ -1,93 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef WEAPON_HL2MPBASE_H
#define WEAPON_HL2MPBASE_H
#ifdef _WIN32
#pragma once
#endif
#include "hl2mp_player_shared.h"
#include "basecombatweapon_shared.h"
#include "hl2mp_weapon_parse.h"
#if defined( CLIENT_DLL )
#define CWeaponHL2MPBase C_WeaponHL2MPBase
void UTIL_ClipPunchAngleOffset( QAngle &in, const QAngle &punch, const QAngle &clip );
#endif
class CHL2MP_Player;
// These are the names of the ammo types that go in the CAmmoDefs and that the
// weapon script files reference.
// Given an ammo type (like from a weapon's GetPrimaryAmmoType()), this compares it
// against the ammo name you specify.
// MIKETODO: this should use indexing instead of searching and strcmp()'ing all the time.
bool IsAmmoType( int iAmmoType, const char *pAmmoName );
class CWeaponHL2MPBase : public CBaseCombatWeapon
{
public:
DECLARE_CLASS( CWeaponHL2MPBase, CBaseCombatWeapon );
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
CWeaponHL2MPBase();
#ifdef GAME_DLL
DECLARE_DATADESC();
void SendReloadSoundEvent( void );
void Materialize( void );
virtual int ObjectCaps( void );
#endif
// All predicted weapons need to implement and return true
virtual bool IsPredicted() const;
CBasePlayer* GetPlayerOwner() const;
CHL2MP_Player* GetHL2MPPlayerOwner() const;
void WeaponSound( WeaponSound_t sound_type, float soundtime = 0.0f );
CHL2MPSWeaponInfo const &GetHL2MPWpnData() const;
virtual void FireBullets( const FireBulletsInfo_t &info );
virtual void FallInit( void );
public:
#if defined( CLIENT_DLL )
virtual bool ShouldPredict();
virtual void OnDataChanged( DataUpdateType_t type );
virtual bool OnFireEvent( C_BaseViewModel *pViewModel, const Vector& origin, const QAngle& angles, int event, const char *options );
#else
virtual void Spawn();
#endif
float m_flPrevAnimTime;
float m_flNextResetCheckTime;
Vector GetOriginalSpawnOrigin( void ) { return m_vOriginalSpawnOrigin; }
QAngle GetOriginalSpawnAngles( void ) { return m_vOriginalSpawnAngles; }
private:
CWeaponHL2MPBase( const CWeaponHL2MPBase & );
Vector m_vOriginalSpawnOrigin;
QAngle m_vOriginalSpawnAngles;
};
#endif // WEAPON_HL2MPBASE_H

View File

@ -1,242 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#if defined( CLIENT_DLL )
#include "c_hl2mp_player.h"
#else
#include "hl2mp_player.h"
#endif
#include "weapon_hl2mpbase_machinegun.h"
#include "in_buttons.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
IMPLEMENT_NETWORKCLASS_ALIASED( HL2MPMachineGun, DT_HL2MPMachineGun )
BEGIN_NETWORK_TABLE( CHL2MPMachineGun, DT_HL2MPMachineGun )
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CHL2MPMachineGun )
END_PREDICTION_DATA()
//=========================================================
// >> CHLSelectFireMachineGun
//=========================================================
BEGIN_DATADESC( CHL2MPMachineGun )
DEFINE_FIELD( m_nShotsFired, FIELD_INTEGER ),
DEFINE_FIELD( m_flNextSoundTime, FIELD_TIME ),
END_DATADESC()
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CHL2MPMachineGun::CHL2MPMachineGun( void )
{
}
const Vector &CHL2MPMachineGun::GetBulletSpread( void )
{
static Vector cone = VECTOR_CONE_3DEGREES;
return cone;
}
//-----------------------------------------------------------------------------
// Purpose:
//
//
//-----------------------------------------------------------------------------
void CHL2MPMachineGun::PrimaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if (!pPlayer)
return;
// Abort here to handle burst and auto fire modes
if ( (UsesClipsForAmmo1() && m_iClip1 == 0) || ( !UsesClipsForAmmo1() && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) )
return;
m_nShotsFired++;
pPlayer->DoMuzzleFlash();
// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems,
// especially if the weapon we're firing has a really fast rate of fire.
int iBulletsToFire = 0;
float fireRate = GetFireRate();
while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
{
// MUST call sound before removing a round from the clip of a CHLMachineGun
WeaponSound(SINGLE, m_flNextPrimaryAttack);
m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate;
iBulletsToFire++;
}
// Make sure we don't fire more than the amount in the clip, if this weapon uses clips
if ( UsesClipsForAmmo1() )
{
if ( iBulletsToFire > m_iClip1 )
iBulletsToFire = m_iClip1;
m_iClip1 -= iBulletsToFire;
}
CHL2MP_Player *pHL2MPPlayer = ToHL2MPPlayer( pPlayer );
// Fire the bullets
FireBulletsInfo_t info;
info.m_iShots = iBulletsToFire;
info.m_vecSrc = pHL2MPPlayer->Weapon_ShootPosition( );
info.m_vecDirShooting = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
info.m_vecSpread = pHL2MPPlayer->GetAttackSpread( this );
info.m_flDistance = MAX_TRACE_LENGTH;
info.m_iAmmoType = m_iPrimaryAmmoType;
info.m_iTracerFreq = 2;
FireBullets( info );
//Factor in the view kick
AddViewKick();
if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
{
// HEV suit - indicate out of ammo condition
pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
}
SendWeaponAnim( GetPrimaryAttackActivity() );
pPlayer->SetAnimation( PLAYER_ATTACK1 );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &info -
//-----------------------------------------------------------------------------
void CHL2MPMachineGun::FireBullets( const FireBulletsInfo_t &info )
{
if(CBasePlayer *pPlayer = ToBasePlayer ( GetOwner() ) )
{
pPlayer->FireBullets(info);
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPMachineGun::DoMachineGunKick( CBasePlayer *pPlayer, float dampEasy, float maxVerticleKickAngle, float fireDurationTime, float slideLimitTime )
{
#define KICK_MIN_X 0.2f //Degrees
#define KICK_MIN_Y 0.2f //Degrees
#define KICK_MIN_Z 0.1f //Degrees
QAngle vecScratch;
int iSeed = CBaseEntity::GetPredictionRandomSeed() & 255;
//Find how far into our accuracy degradation we are
float duration = ( fireDurationTime > slideLimitTime ) ? slideLimitTime : fireDurationTime;
float kickPerc = duration / slideLimitTime;
// do this to get a hard discontinuity, clear out anything under 10 degrees punch
pPlayer->ViewPunchReset( 10 );
//Apply this to the view angles as well
vecScratch.x = -( KICK_MIN_X + ( maxVerticleKickAngle * kickPerc ) );
vecScratch.y = -( KICK_MIN_Y + ( maxVerticleKickAngle * kickPerc ) ) / 3;
vecScratch.z = KICK_MIN_Z + ( maxVerticleKickAngle * kickPerc ) / 8;
RandomSeed( iSeed );
//Wibble left and right
if ( RandomInt( -1, 1 ) >= 0 )
vecScratch.y *= -1;
iSeed++;
//Wobble up and down
if ( RandomInt( -1, 1 ) >= 0 )
vecScratch.z *= -1;
//Clip this to our desired min/max
UTIL_ClipPunchAngleOffset( vecScratch, pPlayer->m_Local.m_vecPunchAngle, QAngle( 24.0f, 3.0f, 1.0f ) );
//Add it to the view punch
// NOTE: 0.5 is just tuned to match the old effect before the punch became simulated
pPlayer->ViewPunch( vecScratch * 0.5 );
}
//-----------------------------------------------------------------------------
// Purpose: Reset our shots fired
//-----------------------------------------------------------------------------
bool CHL2MPMachineGun::Deploy( void )
{
m_nShotsFired = 0;
return BaseClass::Deploy();
}
//-----------------------------------------------------------------------------
// Purpose: Make enough sound events to fill the estimated think interval
// returns: number of shots needed
//-----------------------------------------------------------------------------
int CHL2MPMachineGun::WeaponSoundRealtime( WeaponSound_t shoot_type )
{
int numBullets = 0;
// ran out of time, clamp to current
if (m_flNextSoundTime < gpGlobals->curtime)
{
m_flNextSoundTime = gpGlobals->curtime;
}
// make enough sound events to fill up the next estimated think interval
float dt = clamp( m_flAnimTime - m_flPrevAnimTime, 0, 0.2 );
if (m_flNextSoundTime < gpGlobals->curtime + dt)
{
WeaponSound( SINGLE_NPC, m_flNextSoundTime );
m_flNextSoundTime += GetFireRate();
numBullets++;
}
if (m_flNextSoundTime < gpGlobals->curtime + dt)
{
WeaponSound( SINGLE_NPC, m_flNextSoundTime );
m_flNextSoundTime += GetFireRate();
numBullets++;
}
return numBullets;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHL2MPMachineGun::ItemPostFrame( void )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
// Debounce the recoiling counter
if ( ( pOwner->m_nButtons & IN_ATTACK ) == false )
{
m_nShotsFired = 0;
}
BaseClass::ItemPostFrame();
}

View File

@ -1,58 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "weapon_hl2mpbase.h"
#ifndef BASEHLCOMBATWEAPON_H
#define BASEHLCOMBATWEAPON_H
#ifdef _WIN32
#pragma once
#endif
#if defined( CLIENT_DLL )
#define CHL2MPMachineGun C_HL2MPMachineGun
#endif
//=========================================================
// Machine gun base class
//=========================================================
class CHL2MPMachineGun : public CWeaponHL2MPBase
{
public:
DECLARE_CLASS( CHL2MPMachineGun, CWeaponHL2MPBase );
DECLARE_DATADESC();
CHL2MPMachineGun();
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
void PrimaryAttack( void );
// Default calls through to m_hOwner, but plasma weapons can override and shoot projectiles here.
virtual void ItemPostFrame( void );
virtual void FireBullets( const FireBulletsInfo_t &info );
virtual bool Deploy( void );
virtual const Vector &GetBulletSpread( void );
int WeaponSoundRealtime( WeaponSound_t shoot_type );
// utility function
static void DoMachineGunKick( CBasePlayer *pPlayer, float dampEasy, float maxVerticleKickAngle, float fireDurationTime, float slideLimitTime );
private:
CHL2MPMachineGun( const CHL2MPMachineGun & );
protected:
int m_nShotsFired; // Number of consecutive shots fired
float m_flNextSoundTime; // real-time clock of when to make next sound
};
#endif // BASEHLCOMBATWEAPON_H

View File

@ -1,363 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "weapon_hl2mpbasebasebludgeon.h"
#include "gamerules.h"
#include "ammodef.h"
#include "mathlib/mathlib.h"
#include "in_buttons.h"
#include "animation.h"
#if defined( CLIENT_DLL )
#include "c_hl2mp_player.h"
#else
#include "hl2mp_player.h"
#include "ndebugoverlay.h"
#include "te_effect_dispatch.h"
#include "ilagcompensationmanager.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
IMPLEMENT_NETWORKCLASS_ALIASED( BaseHL2MPBludgeonWeapon, DT_BaseHL2MPBludgeonWeapon )
BEGIN_NETWORK_TABLE( CBaseHL2MPBludgeonWeapon, DT_BaseHL2MPBludgeonWeapon )
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CBaseHL2MPBludgeonWeapon )
END_PREDICTION_DATA()
#define BLUDGEON_HULL_DIM 16
static const Vector g_bludgeonMins(-BLUDGEON_HULL_DIM,-BLUDGEON_HULL_DIM,-BLUDGEON_HULL_DIM);
static const Vector g_bludgeonMaxs(BLUDGEON_HULL_DIM,BLUDGEON_HULL_DIM,BLUDGEON_HULL_DIM);
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CBaseHL2MPBludgeonWeapon::CBaseHL2MPBludgeonWeapon()
{
m_bFiresUnderwater = true;
}
//-----------------------------------------------------------------------------
// Purpose: Spawn the weapon
//-----------------------------------------------------------------------------
void CBaseHL2MPBludgeonWeapon::Spawn( void )
{
m_fMinRange1 = 0;
m_fMinRange2 = 0;
m_fMaxRange1 = 64;
m_fMaxRange2 = 64;
//Call base class first
BaseClass::Spawn();
}
//-----------------------------------------------------------------------------
// Purpose: Precache the weapon
//-----------------------------------------------------------------------------
void CBaseHL2MPBludgeonWeapon::Precache( void )
{
//Call base class first
BaseClass::Precache();
}
//------------------------------------------------------------------------------
// Purpose : Update weapon
//------------------------------------------------------------------------------
void CBaseHL2MPBludgeonWeapon::ItemPostFrame( void )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
if ( (pOwner->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime) )
{
PrimaryAttack();
}
else if ( (pOwner->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime) )
{
SecondaryAttack();
}
else
{
WeaponIdle();
return;
}
}
//------------------------------------------------------------------------------
// Purpose :
// Input :
// Output :
//------------------------------------------------------------------------------
void CBaseHL2MPBludgeonWeapon::PrimaryAttack()
{
#ifndef CLIENT_DLL
CHL2MP_Player *pPlayer = ToHL2MPPlayer( GetPlayerOwner() );
// Move other players back to history positions based on local player's lag
lagcompensation->StartLagCompensation( pPlayer, pPlayer->GetCurrentCommand() );
#endif
Swing( false );
#ifndef CLIENT_DLL
// Move other players back to history positions based on local player's lag
lagcompensation->FinishLagCompensation( pPlayer );
#endif
}
//------------------------------------------------------------------------------
// Purpose :
// Input :
// Output :
//------------------------------------------------------------------------------
void CBaseHL2MPBludgeonWeapon::SecondaryAttack()
{
Swing( true );
}
//------------------------------------------------------------------------------
// Purpose: Implement impact function
//------------------------------------------------------------------------------
void CBaseHL2MPBludgeonWeapon::Hit( trace_t &traceHit, Activity nHitActivity )
{
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
//Do view kick
// AddViewKick();
CBaseEntity *pHitEntity = traceHit.m_pEnt;
//Apply damage to a hit target
if ( pHitEntity != NULL )
{
Vector hitDirection;
pPlayer->EyeVectors( &hitDirection, NULL, NULL );
VectorNormalize( hitDirection );
#ifndef CLIENT_DLL
CTakeDamageInfo info( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB );
if( pPlayer && pHitEntity->IsNPC() )
{
// If bonking an NPC, adjust damage.
info.AdjustPlayerDamageInflictedForSkillLevel();
}
CalculateMeleeDamageForce( &info, hitDirection, traceHit.endpos );
pHitEntity->DispatchTraceAttack( info, hitDirection, &traceHit );
ApplyMultiDamage();
// Now hit all triggers along the ray that...
TraceAttackToTriggers( info, traceHit.startpos, traceHit.endpos, hitDirection );
#endif
WeaponSound( MELEE_HIT );
}
// Apply an impact effect
ImpactEffect( traceHit );
}
Activity CBaseHL2MPBludgeonWeapon::ChooseIntersectionPointAndActivity( trace_t &hitTrace, const Vector &mins, const Vector &maxs, CBasePlayer *pOwner )
{
int i, j, k;
float distance;
const float *minmaxs[2] = {mins.Base(), maxs.Base()};
trace_t tmpTrace;
Vector vecHullEnd = hitTrace.endpos;
Vector vecEnd;
distance = 1e6f;
Vector vecSrc = hitTrace.startpos;
vecHullEnd = vecSrc + ((vecHullEnd - vecSrc)*2);
UTIL_TraceLine( vecSrc, vecHullEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &tmpTrace );
if ( tmpTrace.fraction == 1.0 )
{
for ( i = 0; i < 2; i++ )
{
for ( j = 0; j < 2; j++ )
{
for ( k = 0; k < 2; k++ )
{
vecEnd.x = vecHullEnd.x + minmaxs[i][0];
vecEnd.y = vecHullEnd.y + minmaxs[j][1];
vecEnd.z = vecHullEnd.z + minmaxs[k][2];
UTIL_TraceLine( vecSrc, vecEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &tmpTrace );
if ( tmpTrace.fraction < 1.0 )
{
float thisDistance = (tmpTrace.endpos - vecSrc).Length();
if ( thisDistance < distance )
{
hitTrace = tmpTrace;
distance = thisDistance;
}
}
}
}
}
}
else
{
hitTrace = tmpTrace;
}
return ACT_VM_HITCENTER;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &traceHit -
//-----------------------------------------------------------------------------
bool CBaseHL2MPBludgeonWeapon::ImpactWater( const Vector &start, const Vector &end )
{
//FIXME: This doesn't handle the case of trying to splash while being underwater, but that's not going to look good
// right now anyway...
// We must start outside the water
if ( UTIL_PointContents( start ) & (CONTENTS_WATER|CONTENTS_SLIME))
return false;
// We must end inside of water
if ( !(UTIL_PointContents( end ) & (CONTENTS_WATER|CONTENTS_SLIME)))
return false;
trace_t waterTrace;
UTIL_TraceLine( start, end, (CONTENTS_WATER|CONTENTS_SLIME), GetOwner(), COLLISION_GROUP_NONE, &waterTrace );
if ( waterTrace.fraction < 1.0f )
{
#ifndef CLIENT_DLL
CEffectData data;
data.m_fFlags = 0;
data.m_vOrigin = waterTrace.endpos;
data.m_vNormal = waterTrace.plane.normal;
data.m_flScale = 8.0f;
// See if we hit slime
if ( waterTrace.contents & CONTENTS_SLIME )
{
data.m_fFlags |= FX_WATER_IN_SLIME;
}
DispatchEffect( "watersplash", data );
#endif
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseHL2MPBludgeonWeapon::ImpactEffect( trace_t &traceHit )
{
// See if we hit water (we don't do the other impact effects in this case)
if ( ImpactWater( traceHit.startpos, traceHit.endpos ) )
return;
//FIXME: need new decals
UTIL_ImpactTrace( &traceHit, DMG_CLUB );
}
//------------------------------------------------------------------------------
// Purpose : Starts the swing of the weapon and determines the animation
// Input : bIsSecondary - is this a secondary attack?
//------------------------------------------------------------------------------
void CBaseHL2MPBludgeonWeapon::Swing( int bIsSecondary )
{
trace_t traceHit;
// Try a ray
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( !pOwner )
return;
Vector swingStart = pOwner->Weapon_ShootPosition( );
Vector forward;
pOwner->EyeVectors( &forward, NULL, NULL );
Vector swingEnd = swingStart + forward * GetRange();
UTIL_TraceLine( swingStart, swingEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &traceHit );
Activity nHitActivity = ACT_VM_HITCENTER;
#ifndef CLIENT_DLL
// Like bullets, bludgeon traces have to trace against triggers.
CTakeDamageInfo triggerInfo( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB );
TraceAttackToTriggers( triggerInfo, traceHit.startpos, traceHit.endpos, vec3_origin );
#endif
if ( traceHit.fraction == 1.0 )
{
float bludgeonHullRadius = 1.732f * BLUDGEON_HULL_DIM; // hull is +/- 16, so use cuberoot of 2 to determine how big the hull is from center to the corner point
// Back off by hull "radius"
swingEnd -= forward * bludgeonHullRadius;
UTIL_TraceHull( swingStart, swingEnd, g_bludgeonMins, g_bludgeonMaxs, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &traceHit );
if ( traceHit.fraction < 1.0 && traceHit.m_pEnt )
{
Vector vecToTarget = traceHit.m_pEnt->GetAbsOrigin() - swingStart;
VectorNormalize( vecToTarget );
float dot = vecToTarget.Dot( forward );
// YWB: Make sure they are sort of facing the guy at least...
if ( dot < 0.70721f )
{
// Force amiss
traceHit.fraction = 1.0f;
}
else
{
nHitActivity = ChooseIntersectionPointAndActivity( traceHit, g_bludgeonMins, g_bludgeonMaxs, pOwner );
}
}
}
WeaponSound( SINGLE );
// -------------------------
// Miss
// -------------------------
if ( traceHit.fraction == 1.0f )
{
nHitActivity = bIsSecondary ? ACT_VM_MISSCENTER2 : ACT_VM_MISSCENTER;
// We want to test the first swing again
Vector testEnd = swingStart + forward * GetRange();
// See if we happened to hit water
ImpactWater( swingStart, testEnd );
}
else
{
Hit( traceHit, nHitActivity );
}
// Send the anim
SendWeaponAnim( nHitActivity );
pOwner->SetAnimation( PLAYER_ATTACK1 );
//Setup our next attack times
m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate();
m_flNextSecondaryAttack = gpGlobals->curtime + SequenceDuration();
}

View File

@ -1,66 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: The class from which all bludgeon melee
// weapons are derived.
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//=============================================================================//
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#ifndef BASEBLUDGEONWEAPON_H
#define BASEBLUDGEONWEAPON_H
#ifdef _WIN32
#pragma once
#endif
#if defined( CLIENT_DLL )
#define CBaseHL2MPBludgeonWeapon C_BaseHL2MPBludgeonWeapon
#endif
//=========================================================
// CBaseHLBludgeonWeapon
//=========================================================
class CBaseHL2MPBludgeonWeapon : public CBaseHL2MPCombatWeapon
{
DECLARE_CLASS( CBaseHL2MPBludgeonWeapon, CBaseHL2MPCombatWeapon );
public:
CBaseHL2MPBludgeonWeapon();
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
virtual void Spawn( void );
virtual void Precache( void );
//Attack functions
virtual void PrimaryAttack( void );
virtual void SecondaryAttack( void );
virtual void ItemPostFrame( void );
//Functions to select animation sequences
virtual Activity GetPrimaryAttackActivity( void ) { return ACT_VM_HITCENTER; }
virtual Activity GetSecondaryAttackActivity( void ) { return ACT_VM_HITCENTER2; }
virtual float GetFireRate( void ) { return 0.2f; }
virtual float GetRange( void ) { return 32.0f; }
virtual float GetDamageForActivity( Activity hitActivity ) { return 1.0f; }
CBaseHL2MPBludgeonWeapon( const CBaseHL2MPBludgeonWeapon & );
protected:
virtual void ImpactEffect( trace_t &trace );
private:
bool ImpactWater( const Vector &start, const Vector &end );
void Swing( int bIsSecondary );
void Hit( trace_t &traceHit, Activity nHitActivity );
Activity ChooseIntersectionPointAndActivity( trace_t &hitTrace, const Vector &mins, const Vector &maxs, CBasePlayer *pOwner );
};
#endif

View File

@ -1,416 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#include "hl2mp_player_shared.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
LINK_ENTITY_TO_CLASS( basehl2mpcombatweapon, CBaseHL2MPCombatWeapon );
IMPLEMENT_NETWORKCLASS_ALIASED( BaseHL2MPCombatWeapon , DT_BaseHL2MPCombatWeapon )
BEGIN_NETWORK_TABLE( CBaseHL2MPCombatWeapon , DT_BaseHL2MPCombatWeapon )
#if !defined( CLIENT_DLL )
// SendPropInt( SENDINFO( m_bReflectViewModelAnimations ), 1, SPROP_UNSIGNED ),
#else
// RecvPropInt( RECVINFO( m_bReflectViewModelAnimations ) ),
#endif
END_NETWORK_TABLE()
#if !defined( CLIENT_DLL )
#include "globalstate.h"
//---------------------------------------------------------
// Save/Restore
//---------------------------------------------------------
BEGIN_DATADESC( CBaseHL2MPCombatWeapon )
DEFINE_FIELD( m_bLowered, FIELD_BOOLEAN ),
DEFINE_FIELD( m_flRaiseTime, FIELD_TIME ),
DEFINE_FIELD( m_flHolsterTime, FIELD_TIME ),
END_DATADESC()
#endif
BEGIN_PREDICTION_DATA( CBaseHL2MPCombatWeapon )
END_PREDICTION_DATA()
extern ConVar sk_auto_reload_time;
CBaseHL2MPCombatWeapon::CBaseHL2MPCombatWeapon( void )
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseHL2MPCombatWeapon::ItemHolsterFrame( void )
{
BaseClass::ItemHolsterFrame();
// Must be player held
if ( GetOwner() && GetOwner()->IsPlayer() == false )
return;
// We can't be active
if ( GetOwner()->GetActiveWeapon() == this )
return;
// If it's been longer than three seconds, reload
if ( ( gpGlobals->curtime - m_flHolsterTime ) > sk_auto_reload_time.GetFloat() )
{
// Just load the clip with no animations
FinishReload();
m_flHolsterTime = gpGlobals->curtime;
}
}
//-----------------------------------------------------------------------------
// Purpose: Drops the weapon into a lowered pose
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CBaseHL2MPCombatWeapon::Lower( void )
{
//Don't bother if we don't have the animation
if ( SelectWeightedSequence( ACT_VM_IDLE_LOWERED ) == ACTIVITY_NOT_AVAILABLE )
return false;
m_bLowered = true;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Brings the weapon up to the ready position
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CBaseHL2MPCombatWeapon::Ready( void )
{
//Don't bother if we don't have the animation
if ( SelectWeightedSequence( ACT_VM_LOWERED_TO_IDLE ) == ACTIVITY_NOT_AVAILABLE )
return false;
m_bLowered = false;
m_flRaiseTime = gpGlobals->curtime + 0.5f;
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CBaseHL2MPCombatWeapon::Deploy( void )
{
// If we should be lowered, deploy in the lowered position
// We have to ask the player if the last time it checked, the weapon was lowered
if ( GetOwner() && GetOwner()->IsPlayer() )
{
CHL2MP_Player *pPlayer = assert_cast<CHL2MP_Player*>( GetOwner() );
if ( pPlayer->IsWeaponLowered() )
{
if ( SelectWeightedSequence( ACT_VM_IDLE_LOWERED ) != ACTIVITY_NOT_AVAILABLE )
{
if ( DefaultDeploy( (char*)GetViewModel(), (char*)GetWorldModel(), ACT_VM_IDLE_LOWERED, (char*)GetAnimPrefix() ) )
{
m_bLowered = true;
// Stomp the next attack time to fix the fact that the lower idles are long
pPlayer->SetNextAttack( gpGlobals->curtime + 1.0 );
m_flNextPrimaryAttack = gpGlobals->curtime + 1.0;
m_flNextSecondaryAttack = gpGlobals->curtime + 1.0;
return true;
}
}
}
}
m_bLowered = false;
return BaseClass::Deploy();
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CBaseHL2MPCombatWeapon::Holster( CBaseCombatWeapon *pSwitchingTo )
{
if ( BaseClass::Holster( pSwitchingTo ) )
{
SetWeaponVisible( false );
m_flHolsterTime = gpGlobals->curtime;
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CBaseHL2MPCombatWeapon::WeaponShouldBeLowered( void )
{
// Can't be in the middle of another animation
if ( GetIdealActivity() != ACT_VM_IDLE_LOWERED && GetIdealActivity() != ACT_VM_IDLE &&
GetIdealActivity() != ACT_VM_IDLE_TO_LOWERED && GetIdealActivity() != ACT_VM_LOWERED_TO_IDLE )
return false;
if ( m_bLowered )
return true;
#if !defined( CLIENT_DLL )
if ( GlobalEntity_GetState( "friendly_encounter" ) == GLOBAL_ON )
return true;
#endif
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Allows the weapon to choose proper weapon idle animation
//-----------------------------------------------------------------------------
void CBaseHL2MPCombatWeapon::WeaponIdle( void )
{
//See if we should idle high or low
if ( WeaponShouldBeLowered() )
{
// Move to lowered position if we're not there yet
if ( GetActivity() != ACT_VM_IDLE_LOWERED && GetActivity() != ACT_VM_IDLE_TO_LOWERED
&& GetActivity() != ACT_TRANSITION )
{
SendWeaponAnim( ACT_VM_IDLE_LOWERED );
}
else if ( HasWeaponIdleTimeElapsed() )
{
// Keep idling low
SendWeaponAnim( ACT_VM_IDLE_LOWERED );
}
}
else
{
// See if we need to raise immediately
if ( m_flRaiseTime < gpGlobals->curtime && GetActivity() == ACT_VM_IDLE_LOWERED )
{
SendWeaponAnim( ACT_VM_IDLE );
}
else if ( HasWeaponIdleTimeElapsed() )
{
SendWeaponAnim( ACT_VM_IDLE );
}
}
}
#if defined( CLIENT_DLL )
#define HL2_BOB_CYCLE_MIN 1.0f
#define HL2_BOB_CYCLE_MAX 0.45f
#define HL2_BOB 0.002f
#define HL2_BOB_UP 0.5f
extern float g_lateralBob;
extern float g_verticalBob;
static ConVar cl_bobcycle( "cl_bobcycle","0.8" );
static ConVar cl_bob( "cl_bob","0.002" );
static ConVar cl_bobup( "cl_bobup","0.5" );
// Register these cvars if needed for easy tweaking
static ConVar v_iyaw_cycle( "v_iyaw_cycle", "2", FCVAR_REPLICATED | FCVAR_CHEAT );
static ConVar v_iroll_cycle( "v_iroll_cycle", "0.5", FCVAR_REPLICATED | FCVAR_CHEAT );
static ConVar v_ipitch_cycle( "v_ipitch_cycle", "1", FCVAR_REPLICATED | FCVAR_CHEAT );
static ConVar v_iyaw_level( "v_iyaw_level", "0.3", FCVAR_REPLICATED | FCVAR_CHEAT );
static ConVar v_iroll_level( "v_iroll_level", "0.1", FCVAR_REPLICATED | FCVAR_CHEAT );
static ConVar v_ipitch_level( "v_ipitch_level", "0.3", FCVAR_REPLICATED | FCVAR_CHEAT );
//-----------------------------------------------------------------------------
// Purpose:
// Output : float
//-----------------------------------------------------------------------------
float CBaseHL2MPCombatWeapon::CalcViewmodelBob( void )
{
static float bobtime;
static float lastbobtime;
float cycle;
CBasePlayer *player = ToBasePlayer( GetOwner() );
//Assert( player );
//NOTENOTE: For now, let this cycle continue when in the air, because it snaps badly without it
if ( ( !gpGlobals->frametime ) || ( player == NULL ) )
{
//NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
return 0.0f;// just use old value
}
//Find the speed of the player
float speed = player->GetLocalVelocity().Length2D();
//FIXME: This maximum speed value must come from the server.
// MaxSpeed() is not sufficient for dealing with sprinting - jdw
speed = clamp( speed, -320, 320 );
float bob_offset = RemapVal( speed, 0, 320, 0.0f, 1.0f );
bobtime += ( gpGlobals->curtime - lastbobtime ) * bob_offset;
lastbobtime = gpGlobals->curtime;
//Calculate the vertical bob
cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX)*HL2_BOB_CYCLE_MAX;
cycle /= HL2_BOB_CYCLE_MAX;
if ( cycle < HL2_BOB_UP )
{
cycle = M_PI * cycle / HL2_BOB_UP;
}
else
{
cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP);
}
g_verticalBob = speed*0.005f;
g_verticalBob = g_verticalBob*0.3 + g_verticalBob*0.7*sin(cycle);
g_verticalBob = clamp( g_verticalBob, -7.0f, 4.0f );
//Calculate the lateral bob
cycle = bobtime - (int)(bobtime/HL2_BOB_CYCLE_MAX*2)*HL2_BOB_CYCLE_MAX*2;
cycle /= HL2_BOB_CYCLE_MAX*2;
if ( cycle < HL2_BOB_UP )
{
cycle = M_PI * cycle / HL2_BOB_UP;
}
else
{
cycle = M_PI + M_PI*(cycle-HL2_BOB_UP)/(1.0 - HL2_BOB_UP);
}
g_lateralBob = speed*0.005f;
g_lateralBob = g_lateralBob*0.3 + g_lateralBob*0.7*sin(cycle);
g_lateralBob = clamp( g_lateralBob, -7.0f, 4.0f );
//NOTENOTE: We don't use this return value in our case (need to restructure the calculation function setup!)
return 0.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &origin -
// &angles -
// viewmodelindex -
//-----------------------------------------------------------------------------
void CBaseHL2MPCombatWeapon::AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles )
{
Vector forward, right;
AngleVectors( angles, &forward, &right, NULL );
CalcViewmodelBob();
// Apply bob, but scaled down to 40%
VectorMA( origin, g_verticalBob * 0.1f, forward, origin );
// Z bob a bit more
origin[2] += g_verticalBob * 0.1f;
// bob the angles
angles[ ROLL ] += g_verticalBob * 0.5f;
angles[ PITCH ] -= g_verticalBob * 0.4f;
angles[ YAW ] -= g_lateralBob * 0.3f;
VectorMA( origin, g_lateralBob * 0.8f, right, origin );
}
//-----------------------------------------------------------------------------
Vector CBaseHL2MPCombatWeapon::GetBulletSpread( WeaponProficiency_t proficiency )
{
return BaseClass::GetBulletSpread( proficiency );
}
//-----------------------------------------------------------------------------
float CBaseHL2MPCombatWeapon::GetSpreadBias( WeaponProficiency_t proficiency )
{
return BaseClass::GetSpreadBias( proficiency );
}
//-----------------------------------------------------------------------------
const WeaponProficiencyInfo_t *CBaseHL2MPCombatWeapon::GetProficiencyValues()
{
return NULL;
}
#else
// Server stubs
float CBaseHL2MPCombatWeapon::CalcViewmodelBob( void )
{
return 0.0f;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &origin -
// &angles -
// viewmodelindex -
//-----------------------------------------------------------------------------
void CBaseHL2MPCombatWeapon::AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles )
{
}
//-----------------------------------------------------------------------------
Vector CBaseHL2MPCombatWeapon::GetBulletSpread( WeaponProficiency_t proficiency )
{
Vector baseSpread = BaseClass::GetBulletSpread( proficiency );
const WeaponProficiencyInfo_t *pProficiencyValues = GetProficiencyValues();
float flModifier = (pProficiencyValues)[ proficiency ].spreadscale;
return ( baseSpread * flModifier );
}
//-----------------------------------------------------------------------------
float CBaseHL2MPCombatWeapon::GetSpreadBias( WeaponProficiency_t proficiency )
{
const WeaponProficiencyInfo_t *pProficiencyValues = GetProficiencyValues();
return (pProficiencyValues)[ proficiency ].bias;
}
//-----------------------------------------------------------------------------
const WeaponProficiencyInfo_t *CBaseHL2MPCombatWeapon::GetProficiencyValues()
{
return GetDefaultProficiencyValues();
}
//-----------------------------------------------------------------------------
const WeaponProficiencyInfo_t *CBaseHL2MPCombatWeapon::GetDefaultProficiencyValues()
{
// Weapon proficiency table. Keep this in sync with WeaponProficiency_t enum in the header!!
static WeaponProficiencyInfo_t g_BaseWeaponProficiencyTable[] =
{
{ 2.50, 1.0 },
{ 2.00, 1.0 },
{ 1.50, 1.0 },
{ 1.25, 1.0 },
{ 1.00, 1.0 },
};
COMPILE_TIME_ASSERT( ARRAYSIZE(g_BaseWeaponProficiencyTable) == WEAPON_PROFICIENCY_PERFECT + 1);
return g_BaseWeaponProficiencyTable;
}
#endif

View File

@ -1,63 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#ifndef WEAPON_BASEHL2MPCOMBATWEAPON_SHARED_H
#define WEAPON_BASEHL2MPCOMBATWEAPON_SHARED_H
#ifdef _WIN32
#pragma once
#endif
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#else
#include "hl2mp_player.h"
#endif
#include "weapon_hl2mpbase.h"
#if defined( CLIENT_DLL )
#define CBaseHL2MPCombatWeapon C_BaseHL2MPCombatWeapon
#endif
class CBaseHL2MPCombatWeapon : public CWeaponHL2MPBase
{
#if !defined( CLIENT_DLL )
DECLARE_DATADESC();
#endif
DECLARE_CLASS( CBaseHL2MPCombatWeapon, CWeaponHL2MPBase );
public:
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
CBaseHL2MPCombatWeapon();
virtual bool WeaponShouldBeLowered( void );
virtual bool Ready( void );
virtual bool Lower( void );
virtual bool Deploy( void );
virtual bool Holster( CBaseCombatWeapon *pSwitchingTo );
virtual void WeaponIdle( void );
virtual void AddViewmodelBob( CBaseViewModel *viewmodel, Vector &origin, QAngle &angles );
virtual float CalcViewmodelBob( void );
virtual Vector GetBulletSpread( WeaponProficiency_t proficiency );
virtual float GetSpreadBias( WeaponProficiency_t proficiency );
virtual const WeaponProficiencyInfo_t *GetProficiencyValues();
static const WeaponProficiencyInfo_t *GetDefaultProficiencyValues();
virtual void ItemHolsterFrame( void );
protected:
bool m_bLowered; // Whether the viewmodel is raised or lowered
float m_flRaiseTime; // If lowered, the time we should raise the viewmodel
float m_flHolsterTime; // When the weapon was holstered
private:
CBaseHL2MPCombatWeapon( const CBaseHL2MPCombatWeapon & );
};
#endif // WEAPON_BASEHL2MPCOMBATWEAPON_SHARED_H

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef WEAPON_PHYSCANNON_H
#define WEAPON_PHYSCANNON_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// Do we have the super-phys gun?
//-----------------------------------------------------------------------------
bool PlayerHasMegaPhysCannon();
// force the physcannon to drop an object (if carried)
void PhysCannonForceDrop( CBaseCombatWeapon *pActiveWeapon, CBaseEntity *pOnlyIfHoldingThis );
void PhysCannonBeginUpgrade( CBaseAnimating *pAnim );
bool PlayerPickupControllerIsHoldingEntity( CBaseEntity *pPickupController, CBaseEntity *pHeldEntity );
float PlayerPickupGetHeldObjectMass( CBaseEntity *pPickupControllerEntity, IPhysicsObject *pHeldObject );
float PhysCannonGetHeldObjectMass( CBaseCombatWeapon *pActiveWeapon, IPhysicsObject *pHeldObject );
CBaseEntity *PhysCannonGetHeldEntity( CBaseCombatWeapon *pActiveWeapon );
#endif // WEAPON_PHYSCANNON_H

View File

@ -1,339 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "npcevent.h"
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#else
#include "hl2mp_player.h"
#endif
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#define PISTOL_FASTEST_REFIRE_TIME 0.1f
#define PISTOL_FASTEST_DRY_REFIRE_TIME 0.2f
#define PISTOL_ACCURACY_SHOT_PENALTY_TIME 0.2f // Applied amount of time each shot adds to the time we must recover from
#define PISTOL_ACCURACY_MAXIMUM_PENALTY_TIME 1.5f // Maximum penalty to deal out
#ifdef CLIENT_DLL
#define CWeaponPistol C_WeaponPistol
#endif
//-----------------------------------------------------------------------------
// CWeaponPistol
//-----------------------------------------------------------------------------
class CWeaponPistol : public CBaseHL2MPCombatWeapon
{
public:
DECLARE_CLASS( CWeaponPistol, CBaseHL2MPCombatWeapon );
CWeaponPistol(void);
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
void Precache( void );
void ItemPostFrame( void );
void ItemPreFrame( void );
void ItemBusyFrame( void );
void PrimaryAttack( void );
void AddViewKick( void );
void DryFire( void );
void UpdatePenaltyTime( void );
Activity GetPrimaryAttackActivity( void );
virtual bool Reload( void );
virtual const Vector& GetBulletSpread( void )
{
static Vector cone;
float ramp = RemapValClamped( m_flAccuracyPenalty,
0.0f,
PISTOL_ACCURACY_MAXIMUM_PENALTY_TIME,
0.0f,
1.0f );
// We lerp from very accurate to inaccurate over time
VectorLerp( VECTOR_CONE_1DEGREES, VECTOR_CONE_6DEGREES, ramp, cone );
return cone;
}
virtual int GetMinBurst()
{
return 1;
}
virtual int GetMaxBurst()
{
return 3;
}
virtual float GetFireRate( void )
{
return 0.5f;
}
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
private:
CNetworkVar( float, m_flSoonestPrimaryAttack );
CNetworkVar( float, m_flLastAttackTime );
CNetworkVar( float, m_flAccuracyPenalty );
CNetworkVar( int, m_nNumShotsFired );
private:
CWeaponPistol( const CWeaponPistol & );
};
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponPistol, DT_WeaponPistol )
BEGIN_NETWORK_TABLE( CWeaponPistol, DT_WeaponPistol )
#ifdef CLIENT_DLL
RecvPropTime( RECVINFO( m_flSoonestPrimaryAttack ) ),
RecvPropTime( RECVINFO( m_flLastAttackTime ) ),
RecvPropFloat( RECVINFO( m_flAccuracyPenalty ) ),
RecvPropInt( RECVINFO( m_nNumShotsFired ) ),
#else
SendPropTime( SENDINFO( m_flSoonestPrimaryAttack ) ),
SendPropTime( SENDINFO( m_flLastAttackTime ) ),
SendPropFloat( SENDINFO( m_flAccuracyPenalty ) ),
SendPropInt( SENDINFO( m_nNumShotsFired ) ),
#endif
END_NETWORK_TABLE()
#ifdef CLIENT_DLL
BEGIN_PREDICTION_DATA( CWeaponPistol )
DEFINE_PRED_FIELD( m_flSoonestPrimaryAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_flLastAttackTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_flAccuracyPenalty, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_nNumShotsFired, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
END_PREDICTION_DATA()
#endif
LINK_ENTITY_TO_CLASS( weapon_pistol, CWeaponPistol );
PRECACHE_WEAPON_REGISTER( weapon_pistol );
#ifndef CLIENT_DLL
acttable_t CWeaponPistol::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_PISTOL, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_PISTOL, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_PISTOL, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_PISTOL, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_PISTOL, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_PISTOL, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_PISTOL, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_PISTOL, false },
};
IMPLEMENT_ACTTABLE( CWeaponPistol );
#endif
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CWeaponPistol::CWeaponPistol( void )
{
m_flSoonestPrimaryAttack = gpGlobals->curtime;
m_flAccuracyPenalty = 0.0f;
m_fMinRange1 = 24;
m_fMaxRange1 = 1500;
m_fMinRange2 = 24;
m_fMaxRange2 = 200;
m_bFiresUnderwater = true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponPistol::Precache( void )
{
BaseClass::Precache();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponPistol::DryFire( void )
{
WeaponSound( EMPTY );
SendWeaponAnim( ACT_VM_DRYFIRE );
m_flSoonestPrimaryAttack = gpGlobals->curtime + PISTOL_FASTEST_DRY_REFIRE_TIME;
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponPistol::PrimaryAttack( void )
{
if ( ( gpGlobals->curtime - m_flLastAttackTime ) > 0.5f )
{
m_nNumShotsFired = 0;
}
else
{
m_nNumShotsFired++;
}
m_flLastAttackTime = gpGlobals->curtime;
m_flSoonestPrimaryAttack = gpGlobals->curtime + PISTOL_FASTEST_REFIRE_TIME;
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if( pOwner )
{
// Each time the player fires the pistol, reset the view punch. This prevents
// the aim from 'drifting off' when the player fires very quickly. This may
// not be the ideal way to achieve this, but it's cheap and it works, which is
// great for a feature we're evaluating. (sjb)
pOwner->ViewPunchReset();
}
BaseClass::PrimaryAttack();
// Add an accuracy penalty which can move past our maximum penalty time if we're really spastic
m_flAccuracyPenalty += PISTOL_ACCURACY_SHOT_PENALTY_TIME;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponPistol::UpdatePenaltyTime( void )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
// Check our penalty time decay
if ( ( ( pOwner->m_nButtons & IN_ATTACK ) == false ) && ( m_flSoonestPrimaryAttack < gpGlobals->curtime ) )
{
m_flAccuracyPenalty -= gpGlobals->frametime;
m_flAccuracyPenalty = clamp( m_flAccuracyPenalty, 0.0f, PISTOL_ACCURACY_MAXIMUM_PENALTY_TIME );
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponPistol::ItemPreFrame( void )
{
UpdatePenaltyTime();
BaseClass::ItemPreFrame();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponPistol::ItemBusyFrame( void )
{
UpdatePenaltyTime();
BaseClass::ItemBusyFrame();
}
//-----------------------------------------------------------------------------
// Purpose: Allows firing as fast as button is pressed
//-----------------------------------------------------------------------------
void CWeaponPistol::ItemPostFrame( void )
{
BaseClass::ItemPostFrame();
if ( m_bInReload )
return;
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if ( pOwner == NULL )
return;
if ( pOwner->m_nButtons & IN_ATTACK2 )
{
m_flLastAttackTime = gpGlobals->curtime + PISTOL_FASTEST_REFIRE_TIME;
m_flSoonestPrimaryAttack = gpGlobals->curtime + PISTOL_FASTEST_REFIRE_TIME;
m_flNextPrimaryAttack = gpGlobals->curtime + PISTOL_FASTEST_REFIRE_TIME;
}
//Allow a refire as fast as the player can click
if ( ( ( pOwner->m_nButtons & IN_ATTACK ) == false ) && ( m_flSoonestPrimaryAttack < gpGlobals->curtime ) )
{
m_flNextPrimaryAttack = gpGlobals->curtime - 0.1f;
}
else if ( ( pOwner->m_nButtons & IN_ATTACK ) && ( m_flNextPrimaryAttack < gpGlobals->curtime ) && ( m_iClip1 <= 0 ) )
{
DryFire();
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : int
//-----------------------------------------------------------------------------
Activity CWeaponPistol::GetPrimaryAttackActivity( void )
{
if ( m_nNumShotsFired < 1 )
return ACT_VM_PRIMARYATTACK;
if ( m_nNumShotsFired < 2 )
return ACT_VM_RECOIL1;
if ( m_nNumShotsFired < 3 )
return ACT_VM_RECOIL2;
return ACT_VM_RECOIL3;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CWeaponPistol::Reload( void )
{
bool fRet = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
if ( fRet )
{
WeaponSound( RELOAD );
m_flAccuracyPenalty = 0.0f;
}
return fRet;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponPistol::AddViewKick( void )
{
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if ( pPlayer == NULL )
return;
QAngle viewPunch;
viewPunch.x = SharedRandomFloat( "pistolpax", 0.25f, 0.5f );
viewPunch.y = SharedRandomFloat( "pistolpay", -.6f, .6f );
viewPunch.z = 0.0f;
//Add it to the view punch
pPlayer->ViewPunch( viewPunch );
}

File diff suppressed because it is too large Load Diff

View File

@ -1,267 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef WEAPON_RPG_H
#define WEAPON_RPG_H
#ifdef _WIN32
#pragma once
#endif
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#ifdef CLIENT_DLL
#include "iviewrender_beams.h"
#endif
#ifndef CLIENT_DLL
#include "Sprite.h"
#include "npcevent.h"
#include "beam_shared.h"
class CWeaponRPG;
class CLaserDot;
class RocketTrail;
//###########################################################################
// >> CMissile (missile launcher class is below this one!)
//###########################################################################
class CMissile : public CBaseCombatCharacter
{
DECLARE_CLASS( CMissile, CBaseCombatCharacter );
public:
CMissile();
~CMissile();
#ifdef HL1_DLL
Class_T Classify( void ) { return CLASS_NONE; }
#else
Class_T Classify( void ) { return CLASS_MISSILE; }
#endif
void Spawn( void );
void Precache( void );
void MissileTouch( CBaseEntity *pOther );
void Explode( void );
void ShotDown( void );
void AccelerateThink( void );
void AugerThink( void );
void IgniteThink( void );
void SeekThink( void );
void DumbFire( void );
void SetGracePeriod( float flGracePeriod );
int OnTakeDamage_Alive( const CTakeDamageInfo &info );
void Event_Killed( const CTakeDamageInfo &info );
virtual float GetDamage() { return m_flDamage; }
virtual void SetDamage(float flDamage) { m_flDamage = flDamage; }
unsigned int PhysicsSolidMaskForEntity( void ) const;
CHandle<CWeaponRPG> m_hOwner;
static CMissile *Create( const Vector &vecOrigin, const QAngle &vecAngles, edict_t *pentOwner );
protected:
virtual void DoExplosion();
virtual void ComputeActualDotPosition( CLaserDot *pLaserDot, Vector *pActualDotPosition, float *pHomingSpeed );
virtual int AugerHealth() { return m_iMaxHealth - 20; }
// Creates the smoke trail
void CreateSmokeTrail( void );
// Gets the shooting position
void GetShootPosition( CLaserDot *pLaserDot, Vector *pShootPosition );
CHandle<RocketTrail> m_hRocketTrail;
float m_flAugerTime; // Amount of time to auger before blowing up anyway
float m_flMarkDeadTime;
float m_flDamage;
private:
float m_flGracePeriodEndsAt;
DECLARE_DATADESC();
};
//-----------------------------------------------------------------------------
// Laser dot control
//-----------------------------------------------------------------------------
CBaseEntity *CreateLaserDot( const Vector &origin, CBaseEntity *pOwner, bool bVisibleDot );
void SetLaserDotTarget( CBaseEntity *pLaserDot, CBaseEntity *pTarget );
void EnableLaserDot( CBaseEntity *pLaserDot, bool bEnable );
//-----------------------------------------------------------------------------
// Specialized mizzizzile
//-----------------------------------------------------------------------------
class CAPCMissile : public CMissile
{
DECLARE_CLASS( CMissile, CMissile );
DECLARE_DATADESC();
public:
static CAPCMissile *Create( const Vector &vecOrigin, const QAngle &vecAngles, const Vector &vecVelocity, CBaseEntity *pOwner );
CAPCMissile();
~CAPCMissile();
void IgniteDelay( void );
void AugerDelay( float flDelayTime );
void ExplodeDelay( float flDelayTime );
void DisableGuiding();
#if defined( HL2_DLL )
virtual Class_T Classify ( void ) { return CLASS_COMBINE; }
#endif
void AimAtSpecificTarget( CBaseEntity *pTarget );
void SetGuidanceHint( const char *pHintName );
CAPCMissile *m_pNext;
protected:
virtual void DoExplosion();
virtual void ComputeActualDotPosition( CLaserDot *pLaserDot, Vector *pActualDotPosition, float *pHomingSpeed );
virtual int AugerHealth();
private:
void Init();
void ComputeLeadingPosition( const Vector &vecShootPosition, CBaseEntity *pTarget, Vector *pLeadPosition );
void BeginSeekThink();
void AugerStartThink();
void ExplodeThink();
void APCMissileTouch( CBaseEntity *pOther );
float m_flReachedTargetTime;
float m_flIgnitionTime;
bool m_bGuidingDisabled;
float m_flLastHomingSpeed;
EHANDLE m_hSpecificTarget;
string_t m_strHint;
};
//-----------------------------------------------------------------------------
// Finds apc missiles in cone
//-----------------------------------------------------------------------------
CAPCMissile *FindAPCMissileInCone( const Vector &vecOrigin, const Vector &vecDirection, float flAngle );
#endif
//-----------------------------------------------------------------------------
// RPG
//-----------------------------------------------------------------------------
#ifdef CLIENT_DLL
#define CWeaponRPG C_WeaponRPG
#endif
class CWeaponRPG : public CBaseHL2MPCombatWeapon
{
DECLARE_CLASS( CWeaponRPG, CBaseHL2MPCombatWeapon );
public:
CWeaponRPG();
~CWeaponRPG();
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
void Precache( void );
void PrimaryAttack( void );
virtual float GetFireRate( void ) { return 1; };
void ItemPostFrame( void );
void Activate( void );
void DecrementAmmo( CBaseCombatCharacter *pOwner );
bool Deploy( void );
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
bool Reload( void );
bool WeaponShouldBeLowered( void );
bool Lower( void );
bool CanHolster( void );
virtual void Drop( const Vector &vecVelocity );
int GetMinBurst() { return 1; }
int GetMaxBurst() { return 1; }
float GetMinRestTime() { return 4.0; }
float GetMaxRestTime() { return 4.0; }
void StartGuiding( void );
void StopGuiding( void );
void ToggleGuiding( void );
bool IsGuiding( void );
void NotifyRocketDied( void );
bool HasAnyAmmo( void );
void SuppressGuiding( bool state = true );
void CreateLaserPointer( void );
void UpdateLaserPosition( Vector vecMuzzlePos = vec3_origin, Vector vecEndPos = vec3_origin );
Vector GetLaserPosition( void );
// NPC RPG users cheat and directly set the laser pointer's origin
void UpdateNPCLaserPosition( const Vector &vecTarget );
void SetNPCLaserPosition( const Vector &vecTarget );
const Vector &GetNPCLaserPosition( void );
#ifdef CLIENT_DLL
// We need to render opaque and translucent pieces
virtual RenderGroup_t GetRenderGroup( void ) { return RENDER_GROUP_TWOPASS; }
virtual void NotifyShouldTransmit( ShouldTransmitState_t state );
virtual int DrawModel( int flags );
virtual void ViewModelDrawn( C_BaseViewModel *pBaseViewModel );
virtual bool IsTranslucent( void );
void InitBeam( void );
void GetWeaponAttachment( int attachmentId, Vector &outVector, Vector *dir = NULL );
void DrawEffects( void );
// void DrawLaserDot( void );
CMaterialReference m_hSpriteMaterial; // Used for the laser glint
CMaterialReference m_hBeamMaterial; // Used for the laser beam
Beam_t *m_pBeam; // Laser beam temp entity
#endif //CLIENT_DLL
CBaseEntity *GetMissile( void ) { return m_hMissile; }
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
protected:
CNetworkVar( bool, m_bInitialStateUpdate );
CNetworkVar( bool, m_bGuiding );
CNetworkVar( bool, m_bHideGuiding );
CNetworkHandle( CBaseEntity, m_hMissile );
CNetworkVar( Vector, m_vecLaserDot );
#ifndef CLIENT_DLL
CHandle<CLaserDot> m_hLaserDot;
#endif
private:
CWeaponRPG( const CWeaponRPG & );
};
#endif // WEAPON_RPG_H

View File

@ -1,634 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "npcevent.h"
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#else
#include "hl2mp_player.h"
#endif
#include "weapon_hl2mpbasehlmpcombatweapon.h"
#ifdef CLIENT_DLL
#define CWeaponShotgun C_WeaponShotgun
#endif
extern ConVar sk_auto_reload_time;
extern ConVar sk_plr_num_shotgun_pellets;
class CWeaponShotgun : public CBaseHL2MPCombatWeapon
{
public:
DECLARE_CLASS( CWeaponShotgun, CBaseHL2MPCombatWeapon );
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
private:
CNetworkVar( bool, m_bNeedPump ); // When emptied completely
CNetworkVar( bool, m_bDelayedFire1 ); // Fire primary when finished reloading
CNetworkVar( bool, m_bDelayedFire2 ); // Fire secondary when finished reloading
CNetworkVar( bool, m_bDelayedReload ); // Reload when finished pump
public:
virtual const Vector& GetBulletSpread( void )
{
static Vector cone = VECTOR_CONE_10DEGREES;
return cone;
}
virtual int GetMinBurst() { return 1; }
virtual int GetMaxBurst() { return 3; }
bool StartReload( void );
bool Reload( void );
void FillClip( void );
void FinishReload( void );
void CheckHolsterReload( void );
void Pump( void );
// void WeaponIdle( void );
void ItemHolsterFrame( void );
void ItemPostFrame( void );
void PrimaryAttack( void );
void SecondaryAttack( void );
void DryFire( void );
virtual float GetFireRate( void ) { return 0.7; };
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
CWeaponShotgun(void);
private:
CWeaponShotgun( const CWeaponShotgun & );
};
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponShotgun, DT_WeaponShotgun )
BEGIN_NETWORK_TABLE( CWeaponShotgun, DT_WeaponShotgun )
#ifdef CLIENT_DLL
RecvPropBool( RECVINFO( m_bNeedPump ) ),
RecvPropBool( RECVINFO( m_bDelayedFire1 ) ),
RecvPropBool( RECVINFO( m_bDelayedFire2 ) ),
RecvPropBool( RECVINFO( m_bDelayedReload ) ),
#else
SendPropBool( SENDINFO( m_bNeedPump ) ),
SendPropBool( SENDINFO( m_bDelayedFire1 ) ),
SendPropBool( SENDINFO( m_bDelayedFire2 ) ),
SendPropBool( SENDINFO( m_bDelayedReload ) ),
#endif
END_NETWORK_TABLE()
#ifdef CLIENT_DLL
BEGIN_PREDICTION_DATA( CWeaponShotgun )
DEFINE_PRED_FIELD( m_bNeedPump, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_bDelayedFire1, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_bDelayedFire2, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
DEFINE_PRED_FIELD( m_bDelayedReload, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
END_PREDICTION_DATA()
#endif
LINK_ENTITY_TO_CLASS( weapon_shotgun, CWeaponShotgun );
PRECACHE_WEAPON_REGISTER(weapon_shotgun);
#ifndef CLIENT_DLL
acttable_t CWeaponShotgun::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SHOTGUN, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_SHOTGUN, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SHOTGUN, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SHOTGUN, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SHOTGUN, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SHOTGUN, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SHOTGUN, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SHOTGUN, false },
};
IMPLEMENT_ACTTABLE(CWeaponShotgun);
#endif
//-----------------------------------------------------------------------------
// Purpose: Override so only reload one shell at a time
// Input :
// Output :
//-----------------------------------------------------------------------------
bool CWeaponShotgun::StartReload( void )
{
if ( m_bNeedPump )
return false;
CBaseCombatCharacter *pOwner = GetOwner();
if ( pOwner == NULL )
return false;
if (pOwner->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
return false;
if (m_iClip1 >= GetMaxClip1())
return false;
int j = MIN(1, pOwner->GetAmmoCount(m_iPrimaryAmmoType));
if (j <= 0)
return false;
SendWeaponAnim( ACT_SHOTGUN_RELOAD_START );
// Make shotgun shell visible
SetBodygroup(1,0);
pOwner->m_flNextAttack = gpGlobals->curtime;
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
m_bInReload = true;
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Override so only reload one shell at a time
// Input :
// Output :
//-----------------------------------------------------------------------------
bool CWeaponShotgun::Reload( void )
{
// Check that StartReload was called first
if (!m_bInReload)
{
Warning("ERROR: Shotgun Reload called incorrectly!\n");
}
CBaseCombatCharacter *pOwner = GetOwner();
if ( pOwner == NULL )
return false;
if (pOwner->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
return false;
if (m_iClip1 >= GetMaxClip1())
return false;
int j = MIN(1, pOwner->GetAmmoCount(m_iPrimaryAmmoType));
if (j <= 0)
return false;
FillClip();
// Play reload on different channel as otherwise steals channel away from fire sound
WeaponSound(RELOAD);
SendWeaponAnim( ACT_VM_RELOAD );
pOwner->m_flNextAttack = gpGlobals->curtime;
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Play finish reload anim and fill clip
// Input :
// Output :
//-----------------------------------------------------------------------------
void CWeaponShotgun::FinishReload( void )
{
// Make shotgun shell invisible
SetBodygroup(1,1);
CBaseCombatCharacter *pOwner = GetOwner();
if ( pOwner == NULL )
return;
m_bInReload = false;
// Finish reload animation
SendWeaponAnim( ACT_SHOTGUN_RELOAD_FINISH );
pOwner->m_flNextAttack = gpGlobals->curtime;
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
}
//-----------------------------------------------------------------------------
// Purpose: Play finish reload anim and fill clip
// Input :
// Output :
//-----------------------------------------------------------------------------
void CWeaponShotgun::FillClip( void )
{
CBaseCombatCharacter *pOwner = GetOwner();
if ( pOwner == NULL )
return;
// Add them to the clip
if ( pOwner->GetAmmoCount( m_iPrimaryAmmoType ) > 0 )
{
if ( Clip1() < GetMaxClip1() )
{
m_iClip1++;
pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Play weapon pump anim
// Input :
// Output :
//-----------------------------------------------------------------------------
void CWeaponShotgun::Pump( void )
{
CBaseCombatCharacter *pOwner = GetOwner();
if ( pOwner == NULL )
return;
m_bNeedPump = false;
if ( m_bDelayedReload )
{
m_bDelayedReload = false;
StartReload();
}
WeaponSound( SPECIAL1 );
// Finish reload animation
SendWeaponAnim( ACT_SHOTGUN_PUMP );
pOwner->m_flNextAttack = gpGlobals->curtime + SequenceDuration();
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
}
//-----------------------------------------------------------------------------
// Purpose:
//
//
//-----------------------------------------------------------------------------
void CWeaponShotgun::DryFire( void )
{
WeaponSound(EMPTY);
SendWeaponAnim( ACT_VM_DRYFIRE );
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
}
//-----------------------------------------------------------------------------
// Purpose:
//
//
//-----------------------------------------------------------------------------
void CWeaponShotgun::PrimaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if (!pPlayer)
{
return;
}
// MUST call sound before removing a round from the clip of a CMachineGun
WeaponSound(SINGLE);
pPlayer->DoMuzzleFlash();
SendWeaponAnim( ACT_VM_PRIMARYATTACK );
// Don't fire again until fire animation has completed
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
m_iClip1 -= 1;
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
Vector vecSrc = pPlayer->Weapon_ShootPosition( );
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
FireBulletsInfo_t info( 7, vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
info.m_pAttacker = pPlayer;
// Fire the bullets, and force the first shot to be perfectly accuracy
pPlayer->FireBullets( info );
QAngle punch;
punch.Init( SharedRandomFloat( "shotgunpax", -2, -1 ), SharedRandomFloat( "shotgunpay", -2, 2 ), 0 );
pPlayer->ViewPunch( punch );
if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
{
// HEV suit - indicate out of ammo condition
pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
}
m_bNeedPump = true;
}
//-----------------------------------------------------------------------------
// Purpose:
//
//
//-----------------------------------------------------------------------------
void CWeaponShotgun::SecondaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if (!pPlayer)
{
return;
}
pPlayer->m_nButtons &= ~IN_ATTACK2;
// MUST call sound before removing a round from the clip of a CMachineGun
WeaponSound(WPN_DOUBLE);
pPlayer->DoMuzzleFlash();
SendWeaponAnim( ACT_VM_SECONDARYATTACK );
// Don't fire again until fire animation has completed
m_flNextPrimaryAttack = gpGlobals->curtime + SequenceDuration();
m_iClip1 -= 2; // Shotgun uses same clip for primary and secondary attacks
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
Vector vecSrc = pPlayer->Weapon_ShootPosition();
Vector vecAiming = pPlayer->GetAutoaimVector( AUTOAIM_10DEGREES );
FireBulletsInfo_t info( 12, vecSrc, vecAiming, GetBulletSpread(), MAX_TRACE_LENGTH, m_iPrimaryAmmoType );
info.m_pAttacker = pPlayer;
// Fire the bullets, and force the first shot to be perfectly accuracy
pPlayer->FireBullets( info );
pPlayer->ViewPunch( QAngle(SharedRandomFloat( "shotgunsax", -5, 5 ),0,0) );
if (!m_iClip1 && pPlayer->GetAmmoCount(m_iPrimaryAmmoType) <= 0)
{
// HEV suit - indicate out of ammo condition
pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0);
}
m_bNeedPump = true;
}
//-----------------------------------------------------------------------------
// Purpose: Override so shotgun can do mulitple reloads in a row
//-----------------------------------------------------------------------------
void CWeaponShotgun::ItemPostFrame( void )
{
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
if (!pOwner)
{
return;
}
if ( m_bNeedPump && ( pOwner->m_nButtons & IN_RELOAD ) )
{
m_bDelayedReload = true;
}
if (m_bInReload)
{
// If I'm primary firing and have one round stop reloading and fire
if ((pOwner->m_nButtons & IN_ATTACK ) && (m_iClip1 >=1) && !m_bNeedPump )
{
m_bInReload = false;
m_bNeedPump = false;
m_bDelayedFire1 = true;
}
// If I'm secondary firing and have two rounds stop reloading and fire
else if ((pOwner->m_nButtons & IN_ATTACK2 ) && (m_iClip1 >=2) && !m_bNeedPump )
{
m_bInReload = false;
m_bNeedPump = false;
m_bDelayedFire2 = true;
}
else if (m_flNextPrimaryAttack <= gpGlobals->curtime)
{
// If out of ammo end reload
if (pOwner->GetAmmoCount(m_iPrimaryAmmoType) <=0)
{
FinishReload();
return;
}
// If clip not full reload again
if (m_iClip1 < GetMaxClip1())
{
Reload();
return;
}
// Clip full, stop reloading
else
{
FinishReload();
return;
}
}
}
else
{
// Make shotgun shell invisible
SetBodygroup(1,1);
}
if ((m_bNeedPump) && (m_flNextPrimaryAttack <= gpGlobals->curtime))
{
Pump();
return;
}
// Shotgun uses same timing and ammo for secondary attack
if ((m_bDelayedFire2 || pOwner->m_nButtons & IN_ATTACK2)&&(m_flNextPrimaryAttack <= gpGlobals->curtime))
{
m_bDelayedFire2 = false;
if ( (m_iClip1 <= 1 && UsesClipsForAmmo1()))
{
// If only one shell is left, do a single shot instead
if ( m_iClip1 == 1 )
{
PrimaryAttack();
}
else if (!pOwner->GetAmmoCount(m_iPrimaryAmmoType))
{
DryFire();
}
else
{
StartReload();
}
}
// Fire underwater?
else if (GetOwner()->GetWaterLevel() == 3 && m_bFiresUnderwater == false)
{
WeaponSound(EMPTY);
m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
return;
}
else
{
// If the firing button was just pressed, reset the firing time
if ( pOwner->m_afButtonPressed & IN_ATTACK )
{
m_flNextPrimaryAttack = gpGlobals->curtime;
}
SecondaryAttack();
}
}
else if ( (m_bDelayedFire1 || pOwner->m_nButtons & IN_ATTACK) && m_flNextPrimaryAttack <= gpGlobals->curtime)
{
m_bDelayedFire1 = false;
if ( (m_iClip1 <= 0 && UsesClipsForAmmo1()) || ( !UsesClipsForAmmo1() && !pOwner->GetAmmoCount(m_iPrimaryAmmoType) ) )
{
if (!pOwner->GetAmmoCount(m_iPrimaryAmmoType))
{
DryFire();
}
else
{
StartReload();
}
}
// Fire underwater?
else if (pOwner->GetWaterLevel() == 3 && m_bFiresUnderwater == false)
{
WeaponSound(EMPTY);
m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
return;
}
else
{
// If the firing button was just pressed, reset the firing time
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if ( pPlayer && pPlayer->m_afButtonPressed & IN_ATTACK )
{
m_flNextPrimaryAttack = gpGlobals->curtime;
}
PrimaryAttack();
}
}
if ( pOwner->m_nButtons & IN_RELOAD && UsesClipsForAmmo1() && !m_bInReload )
{
// reload when reload is pressed, or if no buttons are down and weapon is empty.
StartReload();
}
else
{
// no fire buttons down
m_bFireOnEmpty = false;
if ( !HasAnyAmmo() && m_flNextPrimaryAttack < gpGlobals->curtime )
{
// weapon isn't useable, switch.
if ( !(GetWeaponFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) && pOwner->SwitchToNextBestWeapon( this ) )
{
m_flNextPrimaryAttack = gpGlobals->curtime + 0.3;
return;
}
}
else
{
// weapon is useable. Reload if empty and weapon has waited as long as it has to after firing
if ( m_iClip1 <= 0 && !(GetWeaponFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->curtime )
{
if (StartReload())
{
// if we've successfully started to reload, we're done
return;
}
}
}
WeaponIdle( );
return;
}
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CWeaponShotgun::CWeaponShotgun( void )
{
m_bReloadsSingly = true;
m_bNeedPump = false;
m_bDelayedFire1 = false;
m_bDelayedFire2 = false;
m_fMinRange1 = 0.0;
m_fMaxRange1 = 500;
m_fMinRange2 = 0.0;
m_fMaxRange2 = 200;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponShotgun::ItemHolsterFrame( void )
{
// Must be player held
if ( GetOwner() && GetOwner()->IsPlayer() == false )
return;
// We can't be active
if ( GetOwner()->GetActiveWeapon() == this )
return;
// If it's been longer than three seconds, reload
if ( ( gpGlobals->curtime - m_flHolsterTime ) > sk_auto_reload_time.GetFloat() )
{
// Reset the timer
m_flHolsterTime = gpGlobals->curtime;
if ( GetOwner() == NULL )
return;
if ( m_iClip1 == GetMaxClip1() )
return;
// Just load the clip with no animations
int ammoFill = MIN( (GetMaxClip1() - m_iClip1), GetOwner()->GetAmmoCount( GetPrimaryAmmoType() ) );
GetOwner()->RemoveAmmo( ammoFill, GetPrimaryAmmoType() );
m_iClip1 += ammoFill;
}
}
//==================================================
// Purpose:
//==================================================
/*
void CWeaponShotgun::WeaponIdle( void )
{
//Only the player fires this way so we can cast
CBasePlayer *pPlayer = GetOwner()
if ( pPlayer == NULL )
return;
//If we're on a target, play the new anim
if ( pPlayer->IsOnTarget() )
{
SendWeaponAnim( ACT_VM_IDLE_ACTIVE );
}
}
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,91 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: SLAM
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#ifndef WEAPONSLAM_H
#define WEAPONSLAM_H
#include "basegrenade_shared.h"
#include "weapon_hl2mpbasehlmpcombatweapon.h"
enum
{
SLAM_TRIPMINE_READY,
SLAM_SATCHEL_THROW,
SLAM_SATCHEL_ATTACH,
};
#ifdef CLIENT_DLL
#define CWeapon_SLAM C_Weapon_SLAM
#endif
class CWeapon_SLAM : public CBaseHL2MPCombatWeapon
{
public:
DECLARE_CLASS( CWeapon_SLAM, CBaseHL2MPCombatWeapon );
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
CNetworkVar( int, m_tSlamState );
CNetworkVar( bool, m_bDetonatorArmed );
CNetworkVar( bool, m_bNeedDetonatorDraw);
CNetworkVar( bool, m_bNeedDetonatorHolster);
CNetworkVar( bool, m_bNeedReload);
CNetworkVar( bool, m_bClearReload);
CNetworkVar( bool, m_bThrowSatchel);
CNetworkVar( bool, m_bAttachSatchel);
CNetworkVar( bool, m_bAttachTripmine);
float m_flWallSwitchTime;
void Spawn( void );
void Precache( void );
void PrimaryAttack( void );
void SecondaryAttack( void );
void WeaponIdle( void );
void Weapon_Switch( void );
void SLAMThink( void );
void SetPickupTouch( void );
void SlamTouch( CBaseEntity *pOther ); // default weapon touch
void ItemPostFrame( void );
bool Reload( void );
void SetSlamState( int newState );
bool CanAttachSLAM(void); // In position where can attach SLAM?
bool AnyUndetonatedCharges(void);
void StartTripmineAttach( void );
void TripmineAttach( void );
void StartSatchelDetonate( void );
void SatchelDetonate( void );
void StartSatchelThrow( void );
void StartSatchelAttach( void );
void SatchelThrow( void );
void SatchelAttach( void );
bool Deploy( void );
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
CWeapon_SLAM();
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
DECLARE_DATADESC();
#endif
private:
CWeapon_SLAM( const CWeapon_SLAM & );
};
#endif //WEAPONSLAM_H

View File

@ -1,264 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "npcevent.h"
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_hl2mp_player.h"
#else
#include "grenade_ar2.h"
#include "hl2mp_player.h"
#include "basegrenade_shared.h"
#endif
#include "weapon_hl2mpbase.h"
#include "weapon_hl2mpbase_machinegun.h"
#ifdef CLIENT_DLL
#define CWeaponSMG1 C_WeaponSMG1
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define SMG1_GRENADE_DAMAGE 100.0f
#define SMG1_GRENADE_RADIUS 250.0f
class CWeaponSMG1 : public CHL2MPMachineGun
{
public:
DECLARE_CLASS( CWeaponSMG1, CHL2MPMachineGun );
CWeaponSMG1();
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
void Precache( void );
void AddViewKick( void );
void SecondaryAttack( void );
int GetMinBurst() { return 2; }
int GetMaxBurst() { return 5; }
virtual void Equip( CBaseCombatCharacter *pOwner );
bool Reload( void );
float GetFireRate( void ) { return 0.075f; } // 13.3hz
Activity GetPrimaryAttackActivity( void );
virtual const Vector& GetBulletSpread( void )
{
static const Vector cone = VECTOR_CONE_5DEGREES;
return cone;
}
const WeaponProficiencyInfo_t *GetProficiencyValues();
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
protected:
Vector m_vecTossVelocity;
float m_flNextGrenadeCheck;
private:
CWeaponSMG1( const CWeaponSMG1 & );
};
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponSMG1, DT_WeaponSMG1 )
BEGIN_NETWORK_TABLE( CWeaponSMG1, DT_WeaponSMG1 )
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CWeaponSMG1 )
END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_smg1, CWeaponSMG1 );
PRECACHE_WEAPON_REGISTER(weapon_smg1);
#ifndef CLIENT_DLL
acttable_t CWeaponSMG1::m_acttable[] =
{
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_SMG1, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_SMG1, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_SMG1, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_SMG1, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_SMG1, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_SMG1, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_SMG1, false },
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SMG1, false },
};
IMPLEMENT_ACTTABLE(CWeaponSMG1);
#endif
//=========================================================
CWeaponSMG1::CWeaponSMG1( )
{
m_fMinRange1 = 0;// No minimum range.
m_fMaxRange1 = 1400;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponSMG1::Precache( void )
{
#ifndef CLIENT_DLL
UTIL_PrecacheOther("grenade_ar2");
#endif
BaseClass::Precache();
}
//-----------------------------------------------------------------------------
// Purpose: Give this weapon longer range when wielded by an ally NPC.
//-----------------------------------------------------------------------------
void CWeaponSMG1::Equip( CBaseCombatCharacter *pOwner )
{
m_fMaxRange1 = 1400;
BaseClass::Equip( pOwner );
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Activity
//-----------------------------------------------------------------------------
Activity CWeaponSMG1::GetPrimaryAttackActivity( void )
{
if ( m_nShotsFired < 2 )
return ACT_VM_PRIMARYATTACK;
if ( m_nShotsFired < 3 )
return ACT_VM_RECOIL1;
if ( m_nShotsFired < 4 )
return ACT_VM_RECOIL2;
return ACT_VM_RECOIL3;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CWeaponSMG1::Reload( void )
{
bool fRet;
float fCacheTime = m_flNextSecondaryAttack;
fRet = DefaultReload( GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD );
if ( fRet )
{
// Undo whatever the reload process has done to our secondary
// attack timer. We allow you to interrupt reloading to fire
// a grenade.
m_flNextSecondaryAttack = GetOwner()->m_flNextAttack = fCacheTime;
WeaponSound( RELOAD );
}
return fRet;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponSMG1::AddViewKick( void )
{
#define EASY_DAMPEN 0.5f
#define MAX_VERTICAL_KICK 1.0f //Degrees
#define SLIDE_LIMIT 2.0f //Seconds
//Get the view kick
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if ( pPlayer == NULL )
return;
DoMachineGunKick( pPlayer, EASY_DAMPEN, MAX_VERTICAL_KICK, m_fFireDuration, SLIDE_LIMIT );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponSMG1::SecondaryAttack( void )
{
// Only the player fires this way so we can cast
CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
if ( pPlayer == NULL )
return;
//Must have ammo
if ( ( pPlayer->GetAmmoCount( m_iSecondaryAmmoType ) <= 0 ) || ( pPlayer->GetWaterLevel() == 3 ) )
{
SendWeaponAnim( ACT_VM_DRYFIRE );
BaseClass::WeaponSound( EMPTY );
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f;
return;
}
if( m_bInReload )
m_bInReload = false;
// MUST call sound before removing a round from the clip of a CMachineGun
BaseClass::WeaponSound( WPN_DOUBLE );
Vector vecSrc = pPlayer->Weapon_ShootPosition();
Vector vecThrow;
// Don't autoaim on grenade tosses
AngleVectors( pPlayer->EyeAngles() + pPlayer->GetPunchAngle(), &vecThrow );
VectorScale( vecThrow, 1000.0f, vecThrow );
#ifndef CLIENT_DLL
//Create the grenade
CGrenadeAR2 *pGrenade = (CGrenadeAR2*)Create( "grenade_ar2", vecSrc, vec3_angle, pPlayer );
pGrenade->SetAbsVelocity( vecThrow );
pGrenade->SetLocalAngularVelocity( RandomAngle( -400, 400 ) );
pGrenade->SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
pGrenade->SetThrower( GetOwner() );
pGrenade->SetDamage( SMG1_GRENADE_DAMAGE );
pGrenade->SetDamageRadius( SMG1_GRENADE_RADIUS );
#endif
SendWeaponAnim( ACT_VM_SECONDARYATTACK );
// player "shoot" animation
pPlayer->SetAnimation( PLAYER_ATTACK1 );
// Decrease ammo
pPlayer->RemoveAmmo( 1, m_iSecondaryAmmoType );
// Can shoot again immediately
m_flNextPrimaryAttack = gpGlobals->curtime + 0.5f;
// Can blow up after a short delay (so have time to release mouse button)
m_flNextSecondaryAttack = gpGlobals->curtime + 1.0f;
}
//-----------------------------------------------------------------------------
const WeaponProficiencyInfo_t *CWeaponSMG1::GetProficiencyValues()
{
static WeaponProficiencyInfo_t proficiencyTable[] =
{
{ 7.0, 0.75 },
{ 5.00, 0.75 },
{ 10.0/3.0, 0.75 },
{ 5.0/3.0, 0.75 },
{ 1.00, 1.0 },
};
COMPILE_TIME_ASSERT( ARRAYSIZE(proficiencyTable) == WEAPON_PROFICIENCY_PERFECT + 1);
return proficiencyTable;
}

View File

@ -1,902 +0,0 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Stun Stick- beating stick with a zappy end
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "npcevent.h"
#include "weapon_hl2mpbasebasebludgeon.h"
#include "IEffects.h"
#include "debugoverlay_shared.h"
#ifndef CLIENT_DLL
#include "npc_metropolice.h"
#include "te_effect_dispatch.h"
#endif
#ifdef CLIENT_DLL
#include "iviewrender_beams.h"
#include "beam_shared.h"
#include "materialsystem/imaterial.h"
#include "model_types.h"
#include "c_te_effect_dispatch.h"
#include "fx_quad.h"
#include "fx.h"
extern void DrawHalo( IMaterial* pMaterial, const Vector &source, float scale, float const *color, float flHDRColorScale );
extern void FormatViewModelAttachment( Vector &vOrigin, bool bInverse );
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
extern ConVar metropolice_move_and_melee;
#define STUNSTICK_RANGE 75.0f
#define STUNSTICK_REFIRE 0.8f
#define STUNSTICK_BEAM_MATERIAL "sprites/lgtning.vmt"
#define STUNSTICK_GLOW_MATERIAL "sprites/light_glow02_add"
#define STUNSTICK_GLOW_MATERIAL2 "effects/blueflare1"
#define STUNSTICK_GLOW_MATERIAL_NOZ "sprites/light_glow02_add_noz"
#ifdef CLIENT_DLL
#define CWeaponStunStick C_WeaponStunStick
#endif
class CWeaponStunStick : public CBaseHL2MPBludgeonWeapon
{
DECLARE_CLASS( CWeaponStunStick, CBaseHL2MPBludgeonWeapon );
public:
CWeaponStunStick();
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
#ifndef CLIENT_DLL
DECLARE_ACTTABLE();
#endif
#ifdef CLIENT_DLL
virtual int DrawModel( int flags );
virtual void ClientThink( void );
virtual void OnDataChanged( DataUpdateType_t updateType );
virtual RenderGroup_t GetRenderGroup( void );
virtual void ViewModelDrawn( C_BaseViewModel *pBaseViewModel );
#endif
virtual void Precache();
void Spawn();
float GetRange( void ) { return STUNSTICK_RANGE; }
float GetFireRate( void ) { return STUNSTICK_REFIRE; }
bool Deploy( void );
bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL );
void Drop( const Vector &vecVelocity );
void ImpactEffect( trace_t &traceHit );
void SecondaryAttack( void ) {}
void SetStunState( bool state );
bool GetStunState( void );
#ifndef CLIENT_DLL
void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator );
int WeaponMeleeAttack1Condition( float flDot, float flDist );
#endif
float GetDamageForActivity( Activity hitActivity );
CWeaponStunStick( const CWeaponStunStick & );
private:
#ifdef CLIENT_DLL
#define NUM_BEAM_ATTACHMENTS 9
struct stunstickBeamInfo_t
{
int IDs[2]; // 0 - top, 1 - bottom
};
stunstickBeamInfo_t m_BeamAttachments[NUM_BEAM_ATTACHMENTS]; // Lookup for arc attachment points on the head of the stick
int m_BeamCenterAttachment; // "Core" of the effect (center of the head)
void SetupAttachmentPoints( void );
void DrawFirstPersonEffects( void );
void DrawThirdPersonEffects( void );
void DrawEffects( void );
bool InSwing( void );
bool m_bSwungLastFrame;
#define FADE_DURATION 0.25f
float m_flFadeTime;
#endif
CNetworkVar( bool, m_bActive );
};
//-----------------------------------------------------------------------------
// CWeaponStunStick
//-----------------------------------------------------------------------------
IMPLEMENT_NETWORKCLASS_ALIASED( WeaponStunStick, DT_WeaponStunStick )
BEGIN_NETWORK_TABLE( CWeaponStunStick, DT_WeaponStunStick )
#ifdef CLIENT_DLL
RecvPropInt( RECVINFO( m_bActive ) ),
#else
SendPropInt( SENDINFO( m_bActive ), 1, SPROP_UNSIGNED ),
#endif
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CWeaponStunStick )
END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( weapon_stunstick, CWeaponStunStick );
PRECACHE_WEAPON_REGISTER( weapon_stunstick );
#ifndef CLIENT_DLL
acttable_t CWeaponStunStick::m_acttable[] =
{
{ ACT_RANGE_ATTACK1, ACT_RANGE_ATTACK_SLAM, true },
{ ACT_HL2MP_IDLE, ACT_HL2MP_IDLE_MELEE, false },
{ ACT_HL2MP_RUN, ACT_HL2MP_RUN_MELEE, false },
{ ACT_HL2MP_IDLE_CROUCH, ACT_HL2MP_IDLE_CROUCH_MELEE, false },
{ ACT_HL2MP_WALK_CROUCH, ACT_HL2MP_WALK_CROUCH_MELEE, false },
{ ACT_HL2MP_GESTURE_RANGE_ATTACK, ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE, false },
{ ACT_HL2MP_GESTURE_RELOAD, ACT_HL2MP_GESTURE_RELOAD_MELEE, false },
{ ACT_HL2MP_JUMP, ACT_HL2MP_JUMP_MELEE, false },
};
IMPLEMENT_ACTTABLE(CWeaponStunStick);
#endif
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CWeaponStunStick::CWeaponStunStick( void )
{
// HACK: Don't call SetStunState because this tried to Emit a sound before
// any players are connected which is a bug
m_bActive = false;
#ifdef CLIENT_DLL
m_bSwungLastFrame = false;
m_flFadeTime = FADE_DURATION; // Start off past the fade point
#endif
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CWeaponStunStick::Spawn()
{
Precache();
BaseClass::Spawn();
AddSolidFlags( FSOLID_NOT_STANDABLE );
}
void CWeaponStunStick::Precache()
{
BaseClass::Precache();
PrecacheScriptSound( "Weapon_StunStick.Activate" );
PrecacheScriptSound( "Weapon_StunStick.Deactivate" );
PrecacheModel( STUNSTICK_BEAM_MATERIAL );
PrecacheModel( "sprites/light_glow02_add.vmt" );
PrecacheModel( "effects/blueflare1.vmt" );
PrecacheModel( "sprites/light_glow02_add_noz.vmt" );
}
//-----------------------------------------------------------------------------
// Purpose: Get the damage amount for the animation we're doing
// Input : hitActivity - currently played activity
// Output : Damage amount
//-----------------------------------------------------------------------------
float CWeaponStunStick::GetDamageForActivity( Activity hitActivity )
{
return 40.0f;
}
//-----------------------------------------------------------------------------
// Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
//-----------------------------------------------------------------------------
extern ConVar sk_crowbar_lead_time;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponStunStick::ImpactEffect( trace_t &traceHit )
{
//#ifndef CLIENT_DLL
CEffectData data;
data.m_vNormal = traceHit.plane.normal;
data.m_vOrigin = traceHit.endpos + ( data.m_vNormal * 4.0f );
DispatchEffect( "StunstickImpact", data );
//#endif
//FIXME: need new decals
UTIL_ImpactTrace( &traceHit, DMG_CLUB );
}
#ifndef CLIENT_DLL
int CWeaponStunStick::WeaponMeleeAttack1Condition( float flDot, float flDist )
{
// Attempt to lead the target (needed because citizens can't hit manhacks with the crowbar!)
CAI_BaseNPC *pNPC = GetOwner()->MyNPCPointer();
CBaseEntity *pEnemy = pNPC->GetEnemy();
if (!pEnemy)
return COND_NONE;
Vector vecVelocity;
AngularImpulse angVelocity;
pEnemy->GetVelocity( &vecVelocity, &angVelocity );
// Project where the enemy will be in a little while, add some randomness so he doesn't always hit
float dt = sk_crowbar_lead_time.GetFloat();
dt += random->RandomFloat( -0.3f, 0.2f );
if ( dt < 0.0f )
dt = 0.0f;
Vector vecExtrapolatedPos;
VectorMA( pEnemy->WorldSpaceCenter(), dt, vecVelocity, vecExtrapolatedPos );
Vector vecDelta;
VectorSubtract( vecExtrapolatedPos, pNPC->WorldSpaceCenter(), vecDelta );
if ( fabs( vecDelta.z ) > 70 )
{
return COND_TOO_FAR_TO_ATTACK;
}
Vector vecForward = pNPC->BodyDirection2D( );
vecDelta.z = 0.0f;
float flExtrapolatedDot = DotProduct2D( vecDelta.AsVector2D(), vecForward.AsVector2D() );
if ((flDot < 0.7) && (flExtrapolatedDot < 0.7))
{
return COND_NOT_FACING_ATTACK;
}
float flExtrapolatedDist = Vector2DNormalize( vecDelta.AsVector2D() );
if( pEnemy->IsPlayer() )
{
//Vector vecDir = pEnemy->GetSmoothedVelocity();
//float flSpeed = VectorNormalize( vecDir );
// If player will be in front of me in one-half second, clock his arse.
Vector vecProjectEnemy = pEnemy->GetAbsOrigin() + (pEnemy->GetAbsVelocity() * 0.35);
Vector vecProjectMe = GetAbsOrigin();
if( (vecProjectMe - vecProjectEnemy).Length2D() <= 48.0f )
{
return COND_CAN_MELEE_ATTACK1;
}
}
/*
if( metropolice_move_and_melee.GetBool() )
{
if( pNPC->IsMoving() )
{
flTargetDist *= 1.5f;
}
}
*/
float flTargetDist = 48.0f;
if ((flDist > flTargetDist) && (flExtrapolatedDist > flTargetDist))
{
return COND_TOO_FAR_TO_ATTACK;
}
return COND_CAN_MELEE_ATTACK1;
}
void CWeaponStunStick::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator )
{
switch( pEvent->event )
{
case EVENT_WEAPON_MELEE_HIT:
{
// Trace up or down based on where the enemy is...
// But only if we're basically facing that direction
Vector vecDirection;
AngleVectors( GetAbsAngles(), &vecDirection );
CBaseEntity *pEnemy = pOperator->MyNPCPointer() ? pOperator->MyNPCPointer()->GetEnemy() : NULL;
if ( pEnemy )
{
Vector vecDelta;
VectorSubtract( pEnemy->WorldSpaceCenter(), pOperator->Weapon_ShootPosition(), vecDelta );
VectorNormalize( vecDelta );
Vector2D vecDelta2D = vecDelta.AsVector2D();
Vector2DNormalize( vecDelta2D );
if ( DotProduct2D( vecDelta2D, vecDirection.AsVector2D() ) > 0.8f )
{
vecDirection = vecDelta;
}
}
Vector vecEnd;
VectorMA( pOperator->Weapon_ShootPosition(), 32, vecDirection, vecEnd );
// Stretch the swing box down to catch low level physics objects
CBaseEntity *pHurt = pOperator->CheckTraceHullAttack( pOperator->Weapon_ShootPosition(), vecEnd,
Vector(-16,-16,-40), Vector(16,16,16), GetDamageForActivity( GetActivity() ), DMG_CLUB, 0.5f, false );
// did I hit someone?
if ( pHurt )
{
// play sound
WeaponSound( MELEE_HIT );
CBasePlayer *pPlayer = ToBasePlayer( pHurt );
bool bFlashed = false;
// Punch angles
if ( pPlayer != NULL && !(pPlayer->GetFlags() & FL_GODMODE) )
{
float yawKick = random->RandomFloat( -48, -24 );
//Kick the player angles
pPlayer->ViewPunch( QAngle( -16, yawKick, 2 ) );
Vector dir = pHurt->GetAbsOrigin() - GetAbsOrigin();
// If the player's on my head, don't knock him up
if ( pPlayer->GetGroundEntity() == pOperator )
{
dir = vecDirection;
dir.z = 0;
}
VectorNormalize(dir);
dir *= 500.0f;
//If not on ground, then don't make them fly!
if ( !(pPlayer->GetFlags() & FL_ONGROUND ) )
dir.z = 0.0f;
//Push the target back
pHurt->ApplyAbsVelocityImpulse( dir );
if ( !bFlashed )
{
color32 red = {128,0,0,128};
UTIL_ScreenFade( pPlayer, red, 0.5f, 0.1f, FFADE_IN );
}
// Force the player to drop anyting they were holding
pPlayer->ForceDropOfCarriedPhysObjects();
}
// do effect?
}
else
{
WeaponSound( MELEE_MISS );
}
}
break;
default:
BaseClass::Operator_HandleAnimEvent( pEvent, pOperator );
break;
}
}
#endif
//-----------------------------------------------------------------------------
// Purpose: Sets the state of the stun stick
//-----------------------------------------------------------------------------
void CWeaponStunStick::SetStunState( bool state )
{
m_bActive = state;
if ( m_bActive )
{
//FIXME: START - Move to client-side
Vector vecAttachment;
QAngle vecAttachmentAngles;
GetAttachment( 1, vecAttachment, vecAttachmentAngles );
g_pEffects->Sparks( vecAttachment );
//FIXME: END - Move to client-side
EmitSound( "Weapon_StunStick.Activate" );
}
else
{
EmitSound( "Weapon_StunStick.Deactivate" );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponStunStick::Deploy( void )
{
SetStunState( true );
return BaseClass::Deploy();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CWeaponStunStick::Holster( CBaseCombatWeapon *pSwitchingTo )
{
if ( BaseClass::Holster( pSwitchingTo ) == false )
return false;
SetStunState( false );
SetWeaponVisible( false );
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : &vecVelocity -
//-----------------------------------------------------------------------------
void CWeaponStunStick::Drop( const Vector &vecVelocity )
{
SetStunState( false );
#ifndef CLIENT_DLL
UTIL_Remove( this );
#endif
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CWeaponStunStick::GetStunState( void )
{
return m_bActive;
}
#ifdef CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose: Get the attachment point on a viewmodel that a base weapon is using
//-----------------------------------------------------------------------------
bool UTIL_GetWeaponAttachment( C_BaseCombatWeapon *pWeapon, int attachmentID, Vector &absOrigin, QAngle &absAngles )
{
// This is already correct in third-person
if ( pWeapon && pWeapon->ShouldDrawUsingViewModel() == false )
{
return pWeapon->GetAttachment( attachmentID, absOrigin, absAngles );
}
// Otherwise we need to translate the attachment to the viewmodel's version and reformat it
CBasePlayer *pOwner = ToBasePlayer( pWeapon->GetOwner() );
if ( pOwner != NULL )
{
int ret = pOwner->GetViewModel()->GetAttachment( attachmentID, absOrigin, absAngles );
FormatViewModelAttachment( absOrigin, true );
return ret;
}
// Wasn't found
return false;
}
#define BEAM_ATTACH_CORE_NAME "sparkrear"
//-----------------------------------------------------------------------------
// Purpose: Sets up the attachment point lookup for the model
//-----------------------------------------------------------------------------
void C_WeaponStunStick::SetupAttachmentPoints( void )
{
// Setup points for both types of views
if ( ShouldDrawUsingViewModel() )
{
const char *szBeamAttachNamesTop[NUM_BEAM_ATTACHMENTS] =
{
"spark1a","spark2a","spark3a","spark4a",
"spark5a","spark6a","spark7a","spark8a",
"spark9a",
};
const char *szBeamAttachNamesBottom[NUM_BEAM_ATTACHMENTS] =
{
"spark1b","spark2b","spark3b","spark4b",
"spark5b","spark6b","spark7b","spark8b",
"spark9b",
};
// Lookup and store all connections
for ( int i = 0; i < NUM_BEAM_ATTACHMENTS; i++ )
{
m_BeamAttachments[i].IDs[0] = LookupAttachment( szBeamAttachNamesTop[i] );
m_BeamAttachments[i].IDs[1] = LookupAttachment( szBeamAttachNamesBottom[i] );
}
// Setup the center beam point
m_BeamCenterAttachment = LookupAttachment( BEAM_ATTACH_CORE_NAME );
}
else
{
// Setup the center beam point
m_BeamCenterAttachment = 1;
}
}
//-----------------------------------------------------------------------------
// Purpose: Draws the stunstick model (with extra effects)
//-----------------------------------------------------------------------------
int C_WeaponStunStick::DrawModel( int flags )
{
if ( ShouldDraw() == false )
return 0;
// Only render these on the transparent pass
if ( flags & STUDIO_TRANSPARENCY )
{
DrawEffects();
return 1;
}
return BaseClass::DrawModel( flags );
}
//-----------------------------------------------------------------------------
// Purpose: Randomly adds extra effects
//-----------------------------------------------------------------------------
void C_WeaponStunStick::ClientThink( void )
{
if ( InSwing() == false )
{
if ( m_bSwungLastFrame )
{
// Start fading
m_flFadeTime = gpGlobals->curtime;
m_bSwungLastFrame = false;
}
return;
}
// Remember if we were swinging last frame
m_bSwungLastFrame = InSwing();
if ( IsEffectActive( EF_NODRAW ) )
return;
if ( ShouldDrawUsingViewModel() )
{
// Update our effects
if ( gpGlobals->frametime != 0.0f && ( random->RandomInt( 0, 3 ) == 0 ) )
{
Vector vecOrigin;
QAngle vecAngles;
// Inner beams
BeamInfo_t beamInfo;
int attachment = random->RandomInt( 0, 15 );
UTIL_GetWeaponAttachment( this, attachment, vecOrigin, vecAngles );
::FormatViewModelAttachment( vecOrigin, false );
CBasePlayer *pOwner = ToBasePlayer( GetOwner() );
CBaseEntity *pBeamEnt = pOwner->GetViewModel();
beamInfo.m_vecStart = vec3_origin;
beamInfo.m_pStartEnt= pBeamEnt;
beamInfo.m_nStartAttachment = attachment;
beamInfo.m_pEndEnt = NULL;
beamInfo.m_nEndAttachment = -1;
beamInfo.m_vecEnd = vecOrigin + RandomVector( -8, 8 );
beamInfo.m_pszModelName = STUNSTICK_BEAM_MATERIAL;
beamInfo.m_flHaloScale = 0.0f;
beamInfo.m_flLife = 0.05f;
beamInfo.m_flWidth = random->RandomFloat( 1.0f, 2.0f );
beamInfo.m_flEndWidth = 0;
beamInfo.m_flFadeLength = 0.0f;
beamInfo.m_flAmplitude = random->RandomFloat( 16, 32 );
beamInfo.m_flBrightness = 255.0;
beamInfo.m_flSpeed = 0.0;
beamInfo.m_nStartFrame = 0.0;
beamInfo.m_flFrameRate = 1.0f;
beamInfo.m_flRed = 255.0f;;
beamInfo.m_flGreen = 255.0f;
beamInfo.m_flBlue = 255.0f;
beamInfo.m_nSegments = 16;
beamInfo.m_bRenderable = true;
beamInfo.m_nFlags = 0;
beams->CreateBeamEntPoint( beamInfo );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Starts the client-side version thinking
//-----------------------------------------------------------------------------
void C_WeaponStunStick::OnDataChanged( DataUpdateType_t updateType )
{
BaseClass::OnDataChanged( updateType );
if ( updateType == DATA_UPDATE_CREATED )
{
SetNextClientThink( CLIENT_THINK_ALWAYS );
SetupAttachmentPoints();
}
}
//-----------------------------------------------------------------------------
// Purpose: Tells us we're always a translucent entity
//-----------------------------------------------------------------------------
RenderGroup_t C_WeaponStunStick::GetRenderGroup( void )
{
return RENDER_GROUP_TWOPASS;
}
//-----------------------------------------------------------------------------
// Purpose: Tells us we're always a translucent entity
//-----------------------------------------------------------------------------
bool C_WeaponStunStick::InSwing( void )
{
int activity = GetActivity();
// FIXME: This is needed until the actual animation works
if ( ShouldDrawUsingViewModel() == false )
return true;
// These are the swing activities this weapon can play
if ( activity == GetPrimaryAttackActivity() ||
activity == GetSecondaryAttackActivity() ||
activity == ACT_VM_MISSCENTER ||
activity == ACT_VM_MISSCENTER2 )
return true;
return false;
}
//-----------------------------------------------------------------------------
// Purpose: Draw our special effects
//-----------------------------------------------------------------------------
void C_WeaponStunStick::DrawThirdPersonEffects( void )
{
Vector vecOrigin;
QAngle vecAngles;
float color[3];
float scale;
CMatRenderContextPtr pRenderContext( materials );
IMaterial *pMaterial = materials->FindMaterial( STUNSTICK_GLOW_MATERIAL, NULL, false );
pRenderContext->Bind( pMaterial );
// Get bright when swung
if ( InSwing() )
{
color[0] = color[1] = color[2] = 0.4f;
scale = 22.0f;
}
else
{
color[0] = color[1] = color[2] = 0.1f;
scale = 20.0f;
}
// Draw an all encompassing glow around the entire head
UTIL_GetWeaponAttachment( this, m_BeamCenterAttachment, vecOrigin, vecAngles );
DrawHalo( pMaterial, vecOrigin, scale, color );
if ( InSwing() )
{
pMaterial = materials->FindMaterial( STUNSTICK_GLOW_MATERIAL2, NULL, false );
pRenderContext->Bind( pMaterial );
color[0] = color[1] = color[2] = random->RandomFloat( 0.6f, 0.8f );
scale = random->RandomFloat( 4.0f, 6.0f );
// Draw an all encompassing glow around the entire head
UTIL_GetWeaponAttachment( this, m_BeamCenterAttachment, vecOrigin, vecAngles );
DrawHalo( pMaterial, vecOrigin, scale, color );
// Update our effects
if ( gpGlobals->frametime != 0.0f && ( random->RandomInt( 0, 5 ) == 0 ) )
{
Vector vecOrigin;
QAngle vecAngles;
GetAttachment( 1, vecOrigin, vecAngles );
Vector vForward;
AngleVectors( vecAngles, &vForward );
Vector vEnd = vecOrigin - vForward * 1.0f;
// Inner beams
BeamInfo_t beamInfo;
beamInfo.m_vecStart = vEnd;
Vector offset = RandomVector( -12, 8 );
offset += Vector(4,4,4);
beamInfo.m_vecEnd = vecOrigin + offset;
beamInfo.m_pStartEnt= cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
beamInfo.m_pEndEnt = cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
beamInfo.m_nStartAttachment = 1;
beamInfo.m_nEndAttachment = -1;
beamInfo.m_nType = TE_BEAMTESLA;
beamInfo.m_pszModelName = STUNSTICK_BEAM_MATERIAL;
beamInfo.m_flHaloScale = 0.0f;
beamInfo.m_flLife = 0.01f;
beamInfo.m_flWidth = random->RandomFloat( 1.0f, 3.0f );
beamInfo.m_flEndWidth = 0;
beamInfo.m_flFadeLength = 0.0f;
beamInfo.m_flAmplitude = random->RandomFloat( 1, 2 );
beamInfo.m_flBrightness = 255.0;
beamInfo.m_flSpeed = 0.0;
beamInfo.m_nStartFrame = 0.0;
beamInfo.m_flFrameRate = 1.0f;
beamInfo.m_flRed = 255.0f;;
beamInfo.m_flGreen = 255.0f;
beamInfo.m_flBlue = 255.0f;
beamInfo.m_nSegments = 16;
beamInfo.m_bRenderable = true;
beamInfo.m_nFlags = FBEAM_SHADEOUT;
beams->CreateBeamPoints( beamInfo );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Draw our special effects
//-----------------------------------------------------------------------------
void C_WeaponStunStick::DrawFirstPersonEffects( void )
{
Vector vecOrigin;
QAngle vecAngles;
float color[3];
float scale;
CMatRenderContextPtr pRenderContext( materials );
IMaterial *pMaterial = materials->FindMaterial( STUNSTICK_GLOW_MATERIAL_NOZ, NULL, false );
// FIXME: Needs to work with new IMaterial system!
pRenderContext->Bind( pMaterial );
// Find where we are in the fade
float fadeAmount = RemapValClamped( gpGlobals->curtime, m_flFadeTime, m_flFadeTime + FADE_DURATION, 1.0f, 0.1f );
// Get bright when swung
if ( InSwing() )
{
color[0] = color[1] = color[2] = 0.4f;
scale = 22.0f;
}
else
{
color[0] = color[1] = color[2] = 0.4f * fadeAmount;
scale = 20.0f;
}
if ( color[0] > 0.0f )
{
// Draw an all encompassing glow around the entire head
UTIL_GetWeaponAttachment( this, m_BeamCenterAttachment, vecOrigin, vecAngles );
DrawHalo( pMaterial, vecOrigin, scale, color );
}
// Draw bright points at each attachment location
for ( int i = 0; i < (NUM_BEAM_ATTACHMENTS*2)+1; i++ )
{
if ( InSwing() )
{
color[0] = color[1] = color[2] = random->RandomFloat( 0.05f, 0.5f );
scale = random->RandomFloat( 4.0f, 5.0f );
}
else
{
color[0] = color[1] = color[2] = random->RandomFloat( 0.05f, 0.5f ) * fadeAmount;
scale = random->RandomFloat( 4.0f, 5.0f ) * fadeAmount;
}
if ( color[0] > 0.0f )
{
UTIL_GetWeaponAttachment( this, i, vecOrigin, vecAngles );
DrawHalo( pMaterial, vecOrigin, scale, color );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Draw our special effects
//-----------------------------------------------------------------------------
void C_WeaponStunStick::DrawEffects( void )
{
if ( ShouldDrawUsingViewModel() )
{
DrawFirstPersonEffects();
}
else
{
DrawThirdPersonEffects();
}
}
//-----------------------------------------------------------------------------
// Purpose: Viewmodel was drawn
//-----------------------------------------------------------------------------
void C_WeaponStunStick::ViewModelDrawn( C_BaseViewModel *pBaseViewModel )
{
// Don't bother when we're not deployed
if ( IsWeaponVisible() )
{
// Do all our special effects
DrawEffects();
}
BaseClass::ViewModelDrawn( pBaseViewModel );
}
//-----------------------------------------------------------------------------
// Purpose: Draw a cheap glow quad at our impact point (with sparks)
//-----------------------------------------------------------------------------
void StunstickImpactCallback( const CEffectData &data )
{
float scale = random->RandomFloat( 16, 32 );
FX_AddQuad( data.m_vOrigin,
data.m_vNormal,
scale,
scale*2.0f,
1.0f,
1.0f,
0.0f,
0.0f,
random->RandomInt( 0, 360 ),
0,
Vector( 1.0f, 1.0f, 1.0f ),
0.1f,
"sprites/light_glow02_add",
0 );
FX_Sparks( data.m_vOrigin, 1, 2, data.m_vNormal, 6, 64, 256 );
}
DECLARE_CLIENT_EFFECT( "StunstickImpact", StunstickImpactCallback );
#endif

View File

@ -1,8 +1,11 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2013 for Windows Desktop
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
# Visual Studio 2013
#
# Automatically generated solution:
# devtools\bin\vpc /hl2 /episodic +game /mksln games.sln
#
#
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Client (HL2)", "game\client\client_hl2.vcxproj", "{09E5D61D-4897-7B98-288B-C87442D14BFF}"
ProjectSection(ProjectDependencies) = postProject
{BAB92FF0-D72A-D7E5-1988-74628D39B94F} = {BAB92FF0-D72A-D7E5-1988-74628D39B94F}
@ -37,46 +40,3 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tier1", "tier1\tier1.vcxpro
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vgui_controls", "vgui2\vgui_controls\vgui_controls.vcxproj", "{F69B3672-C5E8-CD1A-257F-253A25B5B939}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{09E5D61D-4897-7B98-288B-C87442D14BFF}.Debug|Win32.ActiveCfg = Debug|Win32
{09E5D61D-4897-7B98-288B-C87442D14BFF}.Debug|Win32.Build.0 = Debug|Win32
{09E5D61D-4897-7B98-288B-C87442D14BFF}.Release|Win32.ActiveCfg = Release|Win32
{09E5D61D-4897-7B98-288B-C87442D14BFF}.Release|Win32.Build.0 = Release|Win32
{353A799F-E73F-7A69-07AD-B2AD57F3B775}.Debug|Win32.ActiveCfg = Debug|Win32
{353A799F-E73F-7A69-07AD-B2AD57F3B775}.Debug|Win32.Build.0 = Debug|Win32
{353A799F-E73F-7A69-07AD-B2AD57F3B775}.Release|Win32.ActiveCfg = Release|Win32
{353A799F-E73F-7A69-07AD-B2AD57F3B775}.Release|Win32.Build.0 = Release|Win32
{BAB92FF0-D72A-D7E5-1988-74628D39B94F}.Debug|Win32.ActiveCfg = Debug|Win32
{BAB92FF0-D72A-D7E5-1988-74628D39B94F}.Debug|Win32.Build.0 = Debug|Win32
{BAB92FF0-D72A-D7E5-1988-74628D39B94F}.Release|Win32.ActiveCfg = Release|Win32
{BAB92FF0-D72A-D7E5-1988-74628D39B94F}.Release|Win32.Build.0 = Release|Win32
{95D67225-8415-236F-9128-DCB171B7DEC6}.Debug|Win32.ActiveCfg = Debug|Win32
{95D67225-8415-236F-9128-DCB171B7DEC6}.Debug|Win32.Build.0 = Debug|Win32
{95D67225-8415-236F-9128-DCB171B7DEC6}.Release|Win32.ActiveCfg = Release|Win32
{95D67225-8415-236F-9128-DCB171B7DEC6}.Release|Win32.Build.0 = Release|Win32
{C3EE918E-6836-5578-1FA2-5703048552B9}.Debug|Win32.ActiveCfg = Debug|Win32
{C3EE918E-6836-5578-1FA2-5703048552B9}.Debug|Win32.Build.0 = Debug|Win32
{C3EE918E-6836-5578-1FA2-5703048552B9}.Release|Win32.ActiveCfg = Release|Win32
{C3EE918E-6836-5578-1FA2-5703048552B9}.Release|Win32.Build.0 = Release|Win32
{7855B476-B6D4-535D-F7A9-D623245F8B07}.Debug|Win32.ActiveCfg = Debug|Win32
{7855B476-B6D4-535D-F7A9-D623245F8B07}.Debug|Win32.Build.0 = Debug|Win32
{7855B476-B6D4-535D-F7A9-D623245F8B07}.Release|Win32.ActiveCfg = Release|Win32
{7855B476-B6D4-535D-F7A9-D623245F8B07}.Release|Win32.Build.0 = Release|Win32
{EC1C516D-E1D9-BC0A-F79D-E91E954ED8EC}.Debug|Win32.ActiveCfg = Debug|Win32
{EC1C516D-E1D9-BC0A-F79D-E91E954ED8EC}.Debug|Win32.Build.0 = Debug|Win32
{EC1C516D-E1D9-BC0A-F79D-E91E954ED8EC}.Release|Win32.ActiveCfg = Release|Win32
{EC1C516D-E1D9-BC0A-F79D-E91E954ED8EC}.Release|Win32.Build.0 = Release|Win32
{F69B3672-C5E8-CD1A-257F-253A25B5B939}.Debug|Win32.ActiveCfg = Debug|Win32
{F69B3672-C5E8-CD1A-257F-253A25B5B939}.Debug|Win32.Build.0 = Debug|Win32
{F69B3672-C5E8-CD1A-257F-253A25B5B939}.Release|Win32.ActiveCfg = Release|Win32
{F69B3672-C5E8-CD1A-257F-253A25B5B939}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal