mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-07 17:29:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,985 @@
|
||||
//========= 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();
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
//========= 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
|
||||
@@ -0,0 +1,160 @@
|
||||
//========= 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()
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
//========= 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" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
//========= 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
|
||||
@@ -0,0 +1,116 @@
|
||||
//========= 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;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
//========= 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
|
||||
@@ -0,0 +1,222 @@
|
||||
//========= 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) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
//========= 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();
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
//========= 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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,431 @@
|
||||
//========= 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 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
//========= 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
|
||||
@@ -0,0 +1,653 @@
|
||||
//========= 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
//========= 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
|
||||
@@ -0,0 +1,174 @@
|
||||
//========= 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
//========= 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
|
||||
Reference in New Issue
Block a user