mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-04 18:09:53 +03:00
1
This commit is contained in:
29
game/client/hl2/C_Func_Monitor.cpp
Normal file
29
game/client/hl2/C_Func_Monitor.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class C_FuncMonitor : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_FuncMonitor, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
// C_BaseEntity.
|
||||
public:
|
||||
virtual bool ShouldDraw();
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_FuncMonitor, DT_FuncMonitor, CFuncMonitor )
|
||||
END_RECV_TABLE()
|
||||
|
||||
bool C_FuncMonitor::ShouldDraw()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
219
game/client/hl2/c_antlion_dust.cpp
Normal file
219
game/client/hl2/c_antlion_dust.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "fx.h"
|
||||
#include "particlemgr.h"
|
||||
#include "particle_prototype.h"
|
||||
#include "particle_util.h"
|
||||
#include "c_te_particlesystem.h"
|
||||
#include "particles_ez.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define DUST_STARTSIZE 16
|
||||
#define DUST_ENDSIZE 48
|
||||
#define DUST_RADIUS 32.0f
|
||||
#define DUST_STARTALPHA 0.3f
|
||||
#define DUST_ENDALPHA 0.0f
|
||||
#define DUST_LIFETIME 2.0f
|
||||
|
||||
static Vector g_AntlionDustColor( 0.3f, 0.25f, 0.2f );
|
||||
|
||||
extern IPhysicsSurfaceProps *physprops;
|
||||
|
||||
class CAntlionDustEmitter : public CSimpleEmitter
|
||||
{
|
||||
public:
|
||||
static CAntlionDustEmitter *Create( const char *debugname )
|
||||
{
|
||||
return new CAntlionDustEmitter( debugname );
|
||||
}
|
||||
|
||||
void UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
|
||||
{
|
||||
//FIXME: Incorrect
|
||||
pParticle->m_vecVelocity *= 0.9f;
|
||||
}
|
||||
|
||||
private:
|
||||
CAntlionDustEmitter( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
|
||||
CAntlionDustEmitter( const CAntlionDustEmitter & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
//==================================================
|
||||
// C_TEAntlionDust
|
||||
//==================================================
|
||||
|
||||
class C_TEAntlionDust: public C_TEParticleSystem
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_TEAntlionDust, C_TEParticleSystem );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_TEAntlionDust();
|
||||
virtual ~C_TEAntlionDust();
|
||||
|
||||
//C_BaseEntity
|
||||
public:
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
virtual bool ShouldDraw() { return true; }
|
||||
|
||||
|
||||
//IParticleEffect
|
||||
public:
|
||||
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||
|
||||
public:
|
||||
PMaterialHandle m_MaterialHandle;
|
||||
|
||||
Vector m_vecOrigin;
|
||||
QAngle m_vecAngles;
|
||||
bool m_bBlockedSpawner;
|
||||
|
||||
protected:
|
||||
void GetDustColor( Vector &color );
|
||||
};
|
||||
|
||||
// Expose to the particle app.
|
||||
EXPOSE_PROTOTYPE_EFFECT( AntlionDust, C_TEAntlionDust );
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TEAntlionDust, DT_TEAntlionDust, CTEAntlionDust )
|
||||
RecvPropVector(RECVINFO( m_vecOrigin )),
|
||||
RecvPropVector(RECVINFO( m_vecAngles )),
|
||||
RecvPropBool(RECVINFO( m_bBlockedSpawner )),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//==================================================
|
||||
// C_TEAntlionDust
|
||||
//==================================================
|
||||
|
||||
C_TEAntlionDust::C_TEAntlionDust()
|
||||
{
|
||||
m_MaterialHandle = INVALID_MATERIAL_HANDLE;
|
||||
m_vecOrigin.Init();
|
||||
m_vecAngles.Init();
|
||||
m_bBlockedSpawner = false;
|
||||
}
|
||||
|
||||
C_TEAntlionDust::~C_TEAntlionDust()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bNewEntity - whether or not to start a new entity
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_TEAntlionDust::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
// This style of creating dust emitters is now deprecated; we use the simple particle singleton exclusively.
|
||||
/*
|
||||
CSmartPtr<CAntlionDustEmitter> pDustEmitter = CAntlionDustEmitter::Create( "TEAntlionDust" );
|
||||
Assert( pDustEmitter );
|
||||
if ( pDustEmitter == NULL )
|
||||
return;
|
||||
|
||||
pDustEmitter->SetSortOrigin( m_vecOrigin );
|
||||
pDustEmitter->SetNearClip( 32, 64 );
|
||||
pDustEmitter->GetBinding().SetBBox( m_vecOrigin - Vector( 32, 32, 32 ), m_vecOrigin + Vector( 32, 32, 32 ) );
|
||||
*/
|
||||
|
||||
Vector offset;
|
||||
Vector vecColor;
|
||||
GetDustColor( vecColor );
|
||||
|
||||
int iParticleCount = 16;
|
||||
|
||||
if ( m_bBlockedSpawner == true )
|
||||
{
|
||||
iParticleCount = 8;
|
||||
}
|
||||
|
||||
//Spawn the dust
|
||||
SimpleParticle particle;
|
||||
for ( int i = 0; i < iParticleCount; i++ )
|
||||
{
|
||||
//Offset this dust puff's origin
|
||||
offset[0] = random->RandomFloat( -DUST_RADIUS, DUST_RADIUS );
|
||||
offset[1] = random->RandomFloat( -DUST_RADIUS, DUST_RADIUS );
|
||||
offset[2] = random->RandomFloat( -16, 8 );
|
||||
|
||||
offset += m_vecOrigin;
|
||||
|
||||
particle.m_Pos = offset;
|
||||
particle.m_flDieTime = random->RandomFloat( 0.75f, 1.25f );
|
||||
particle.m_flLifetime = 0.0f;
|
||||
|
||||
Vector dir = particle.m_Pos - m_vecOrigin;
|
||||
particle.m_vecVelocity = dir * random->RandomFloat( 0.5f, 1.0f );
|
||||
dir.z = fabs(dir.z);
|
||||
|
||||
float colorRamp = random->RandomFloat( 0.5f, 1.0f );
|
||||
Vector color = vecColor*colorRamp;
|
||||
|
||||
color[0] = clamp( color[0], 0.0f, 1.0f );
|
||||
color[1] = clamp( color[1], 0.0f, 1.0f );
|
||||
color[2] = clamp( color[2], 0.0f, 1.0f );
|
||||
|
||||
color *= 255;
|
||||
|
||||
particle.m_uchColor[0] = color[0];
|
||||
particle.m_uchColor[1] = color[1];
|
||||
particle.m_uchColor[2] = color[2];
|
||||
|
||||
particle.m_uchStartAlpha= random->RandomFloat( 64, 128 );
|
||||
particle.m_uchEndAlpha = 0;
|
||||
|
||||
particle.m_uchStartSize = random->RandomInt( 16, 32 );
|
||||
particle.m_uchEndSize = particle.m_uchStartSize * 3;
|
||||
particle.m_flRoll = random->RandomInt( 0, 360 );
|
||||
particle.m_flRollDelta = random->RandomFloat( -0.2f, 0.2f );
|
||||
|
||||
// Though it appears there are two particle handle entries in g_Mat_DustPuff, in fact
|
||||
// only the one present at index 0 actually draws. Trying to spawn a particle with
|
||||
// the other material will give you no particle at all. Therefore while instead of this:
|
||||
// AddSimpleParticle( &particle, g_Mat_DustPuff[random->RandomInt(0,1) );
|
||||
// we have to do this:
|
||||
AddSimpleParticle( &particle, g_Mat_DustPuff[0] );
|
||||
}
|
||||
}
|
||||
|
||||
void GetColorForSurface( trace_t *trace, Vector *color );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &color -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TEAntlionDust::GetDustColor( Vector &color )
|
||||
{
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( m_vecOrigin+Vector(0,0,1), m_vecOrigin+Vector(0,0,-32),
|
||||
MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
if ( tr.fraction < 1.0f )
|
||||
{
|
||||
GetColorForSurface( &tr, &color );
|
||||
}
|
||||
else
|
||||
{
|
||||
//Fill in a fallback
|
||||
color = g_AntlionDustColor;
|
||||
}
|
||||
}
|
||||
|
||||
void C_TEAntlionDust::RenderParticles( CParticleRenderIterator *pIterator )
|
||||
{
|
||||
}
|
||||
|
||||
void C_TEAntlionDust::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||
{
|
||||
}
|
||||
|
||||
475
game/client/hl2/c_ar2_explosion.cpp
Normal file
475
game/client/hl2/c_ar2_explosion.cpp
Normal file
@@ -0,0 +1,475 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "particlemgr.h"
|
||||
#include "particle_prototype.h"
|
||||
#include "particle_util.h"
|
||||
#include "surfinfo.h"
|
||||
#include "baseparticleentity.h"
|
||||
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
// Definitions
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
||||
#define NUM_AR2_EXPLOSION_PARTICLES 70
|
||||
#define AR2_DUST_RADIUS 240 // 340
|
||||
#define AR2_DUST_LIFETIME 4
|
||||
#define AR2_DUST_LIFETIME_DELTA 6
|
||||
#define AR2_DUST_SPEED 10000
|
||||
#define AR2_DUST_STARTSIZE 8
|
||||
#define AR2_DUST_ENDSIZE 32
|
||||
#define AR2_DUST_ALPHA 0.5f
|
||||
#define AR2_DUST_FADE_IN_TIME 0.25f
|
||||
|
||||
static Vector g_AR2DustColor1(0.35, 0.345, 0.33 );
|
||||
static Vector g_AR2DustColor2(0.75, 0.75, 0.7);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
// Classes
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
||||
class C_AR2Explosion : public C_BaseParticleEntity, public IPrototypeAppEffect
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_AR2Explosion, C_BaseParticleEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_AR2Explosion();
|
||||
~C_AR2Explosion();
|
||||
|
||||
private:
|
||||
|
||||
class AR2ExplosionParticle : public StandardParticle_t
|
||||
{
|
||||
public:
|
||||
float m_Dist;
|
||||
Vector m_Start;
|
||||
float m_Roll;
|
||||
float m_RollSpeed;
|
||||
float m_Dwell;
|
||||
};
|
||||
|
||||
// C_BaseEntity.
|
||||
public:
|
||||
virtual void OnDataChanged(DataUpdateType_t updateType);
|
||||
|
||||
// IPrototypeAppEffect.
|
||||
public:
|
||||
virtual void Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs);
|
||||
|
||||
// IParticleEffect.
|
||||
public:
|
||||
virtual void Update(float fTimeDelta);
|
||||
|
||||
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||
|
||||
|
||||
public:
|
||||
CParticleMgr *m_pParticleMgr;
|
||||
PMaterialHandle m_MaterialHandle;
|
||||
|
||||
private:
|
||||
|
||||
char m_szMaterialName[255];
|
||||
|
||||
C_AR2Explosion( const C_AR2Explosion & );
|
||||
};
|
||||
|
||||
// Expose to the particle app.
|
||||
EXPOSE_PROTOTYPE_EFFECT(AR2Explosion, C_AR2Explosion);
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_AR2Explosion, DT_AR2Explosion, AR2Explosion)
|
||||
RecvPropString( RECVINFO( m_szMaterialName ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
// Helpers.
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
||||
// Given a line segment from vStart to vEnd
|
||||
// and a list of convex polygons in pSurfInfos and nSurfInfos,
|
||||
// fill in the list of which polygons the segment intersects.
|
||||
// Returns the number of intersected surfaces.
|
||||
static int IntersectSegmentWithSurfInfos(
|
||||
const Vector &vStart,
|
||||
const Vector &vEnd,
|
||||
SurfInfo *pSurfInfos,
|
||||
const int nSurfInfos,
|
||||
SurfInfo ** pIntersections,
|
||||
Vector *pIntersectionPositions,
|
||||
int nMaxIntersections)
|
||||
{
|
||||
if(nMaxIntersections == 0)
|
||||
return 0;
|
||||
|
||||
int nIntersections = 0;
|
||||
for(int i=0; i < nSurfInfos; i++)
|
||||
{
|
||||
SurfInfo *pSurf = &pSurfInfos[i];
|
||||
|
||||
// Does it intersect the plane?
|
||||
float dot1 = pSurf->m_Plane.DistTo(vStart);
|
||||
float dot2 = pSurf->m_Plane.DistTo(vEnd);
|
||||
if((dot1 > 0) != (dot2 > 0))
|
||||
{
|
||||
float t = dot1 / (dot1 - dot2);
|
||||
Vector vIntersection = vStart + (vEnd - vStart) * t;
|
||||
|
||||
// If the intersection is behind any edge plane, then it's not inside the polygon.
|
||||
unsigned long iEdge;
|
||||
for(iEdge=0; iEdge < pSurf->m_nVerts; iEdge++)
|
||||
{
|
||||
VPlane edgePlane;
|
||||
edgePlane.m_Normal = pSurf->m_Plane.m_Normal.Cross(pSurf->m_Verts[iEdge] - pSurf->m_Verts[(iEdge+1)%pSurf->m_nVerts]);
|
||||
VectorNormalize( edgePlane.m_Normal );
|
||||
edgePlane.m_Dist = edgePlane.m_Normal.Dot(pSurf->m_Verts[iEdge]);
|
||||
|
||||
if(edgePlane.DistTo(vIntersection) < 0.0f)
|
||||
break;
|
||||
}
|
||||
|
||||
if(iEdge == pSurf->m_nVerts)
|
||||
{
|
||||
pIntersections[nIntersections] = pSurf;
|
||||
pIntersectionPositions[nIntersections] = vIntersection;
|
||||
++nIntersections;
|
||||
if(nIntersections >= nMaxIntersections)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nIntersections;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
// C_AR2Explosion
|
||||
// ------------------------------------------------------------------------- //
|
||||
C_AR2Explosion::C_AR2Explosion()
|
||||
{
|
||||
m_pParticleMgr = NULL;
|
||||
m_MaterialHandle = INVALID_MATERIAL_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
C_AR2Explosion::~C_AR2Explosion()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void C_AR2Explosion::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
C_BaseEntity::OnDataChanged(updateType);
|
||||
|
||||
if(updateType == DATA_UPDATE_CREATED)
|
||||
{
|
||||
Start(ParticleMgr(), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static ConVar mat_reduceparticles( "mat_reduceparticles", "0" );
|
||||
|
||||
void C_AR2Explosion::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs)
|
||||
{
|
||||
m_pParticleMgr = pParticleMgr;
|
||||
if(!pParticleMgr->AddEffect(&m_ParticleEffect, this))
|
||||
return;
|
||||
|
||||
if (!m_szMaterialName[0])
|
||||
{
|
||||
Q_strncpy(m_szMaterialName, "particle/particle_noisesphere", sizeof( m_szMaterialName ) );
|
||||
}
|
||||
|
||||
m_MaterialHandle = m_ParticleEffect.FindOrAddMaterial(m_szMaterialName);
|
||||
|
||||
// Precalculate stuff for the particle spawning..
|
||||
#define NUM_DUSTEMITTER_SURFINFOS 128
|
||||
SurfInfo surfInfos[NUM_DUSTEMITTER_SURFINFOS];
|
||||
int nSurfInfos;
|
||||
|
||||
// Center of explosion.
|
||||
Vector vCenter = GetAbsOrigin(); // HACKHACK.. when the engine bug is fixed, use origin.
|
||||
|
||||
if ( IsXbox() )
|
||||
{
|
||||
m_ParticleEffect.SetBBox( vCenter-Vector(300,300,300), vCenter+Vector(300,300,300) );
|
||||
}
|
||||
|
||||
#ifdef PARTICLEPROTOTYPE_APP
|
||||
float surfSize = 10000;
|
||||
nSurfInfos = 1;
|
||||
surfInfos[0].m_Verts[0].Init(-surfSize,-surfSize,0);
|
||||
surfInfos[0].m_Verts[1].Init(-surfSize,surfSize,0);
|
||||
surfInfos[0].m_Verts[2].Init(surfSize, surfSize,0);
|
||||
surfInfos[0].m_Verts[3].Init(surfSize,-surfSize,0);
|
||||
surfInfos[0].m_nVerts = 4;
|
||||
surfInfos[0].m_Plane.m_Normal.Init(0,0,1);
|
||||
surfInfos[0].m_Plane.m_Dist = -3;
|
||||
#else
|
||||
{
|
||||
nSurfInfos = 0;
|
||||
C_BaseEntity *ent = cl_entitylist->GetEnt( 0 );
|
||||
if ( ent )
|
||||
{
|
||||
nSurfInfos = engine->GetIntersectingSurfaces(
|
||||
ent->GetModel(),
|
||||
vCenter,
|
||||
AR2_DUST_RADIUS,
|
||||
true,
|
||||
surfInfos,
|
||||
NUM_DUSTEMITTER_SURFINFOS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int nParticles = 0;
|
||||
|
||||
int iParticlesToSpawn = NUM_AR2_EXPLOSION_PARTICLES;
|
||||
|
||||
// In DX7, much fewer particles
|
||||
if ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 80 )
|
||||
{
|
||||
iParticlesToSpawn *= 0.25;
|
||||
}
|
||||
else if ( mat_reduceparticles.GetBool() )
|
||||
{
|
||||
iParticlesToSpawn *= 0.025;
|
||||
}
|
||||
|
||||
if( nSurfInfos > 0 )
|
||||
{
|
||||
// For nParticles*N, generate a ray and cast it out. If it hits anything, spawn a particle there.
|
||||
int nTestsPerParticle=3;
|
||||
for(int i=0; i < iParticlesToSpawn; i++)
|
||||
{
|
||||
for(int iTest=0; iTest < nTestsPerParticle; iTest++)
|
||||
{
|
||||
Vector randVec = RandomVector(-1,1);
|
||||
VectorNormalize( randVec );
|
||||
Vector startPos = vCenter + randVec * AR2_DUST_RADIUS;
|
||||
|
||||
randVec = RandomVector(-1,1);
|
||||
VectorNormalize( randVec );
|
||||
Vector endPos = vCenter + randVec * AR2_DUST_RADIUS;
|
||||
|
||||
#define MAX_SURFINFO_INTERSECTIONS 4
|
||||
SurfInfo *pIntersected[MAX_SURFINFO_INTERSECTIONS];
|
||||
Vector vIntersections[MAX_SURFINFO_INTERSECTIONS];
|
||||
int nIntersections;
|
||||
nIntersections = IntersectSegmentWithSurfInfos(
|
||||
startPos,
|
||||
endPos,
|
||||
surfInfos,
|
||||
nSurfInfos,
|
||||
pIntersected,
|
||||
vIntersections,
|
||||
MAX_SURFINFO_INTERSECTIONS);
|
||||
|
||||
if(nIntersections)
|
||||
{
|
||||
int iIntersection = rand() % nIntersections;
|
||||
|
||||
Vector velocity;
|
||||
//velocity.Init(-1.0f + ((float)rand()/VALVE_RAND_MAX) * 2.0f, -1.0f + ((float)rand()/VALVE_RAND_MAX) * 2.0f, -1.0f + ((float)rand()/VALVE_RAND_MAX) * 2.0f);
|
||||
//velocity = velocity * FRand(m_MinSpeed, m_MaxSpeed);
|
||||
Vector direction = (vIntersections[iIntersection] - vCenter );
|
||||
float dist = VectorNormalize( direction );
|
||||
if(dist > AR2_DUST_RADIUS)
|
||||
dist = AR2_DUST_RADIUS;
|
||||
|
||||
static float power = 2.0f;
|
||||
float falloffMul = pow(1.0f - dist / AR2_DUST_RADIUS, power);
|
||||
|
||||
Vector reflection = direction - 2 * DotProduct( direction, pIntersected[iIntersection]->m_Plane.m_Normal ) * pIntersected[iIntersection]->m_Plane.m_Normal;
|
||||
VectorNormalize( reflection );
|
||||
|
||||
velocity = reflection * AR2_DUST_SPEED * falloffMul;
|
||||
// velocity = velocity + (vIntersections[iIntersection] - vCenter) * falloffMul;
|
||||
|
||||
|
||||
/*
|
||||
debugoverlay->AddLineOverlay( vIntersections[iIntersection],
|
||||
vIntersections[iIntersection] + reflection * 64,
|
||||
128, 128, 255, false, 15.0 );
|
||||
*/
|
||||
#if 1
|
||||
AR2ExplosionParticle *pParticle =
|
||||
(AR2ExplosionParticle*)m_ParticleEffect.AddParticle( sizeof(AR2ExplosionParticle), m_MaterialHandle );
|
||||
|
||||
if(pParticle)
|
||||
{
|
||||
pParticle->m_Pos = vIntersections[iIntersection];
|
||||
pParticle->m_Start = pParticle->m_Pos;
|
||||
pParticle->m_Dist = 8.0;
|
||||
pParticle->m_Velocity = velocity;
|
||||
// sound == 13031.496062992125984251968503937ips
|
||||
pParticle->m_Lifetime = -dist / 13031.5f - 0.1;
|
||||
pParticle->m_Roll = FRand( 0, M_PI * 2 );
|
||||
pParticle->m_RollSpeed = FRand( -1, 1 ) * 0.4;
|
||||
pParticle->m_Dwell = AR2_DUST_LIFETIME + random->RandomFloat( 0, AR2_DUST_LIFETIME_DELTA );
|
||||
nParticles++;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build interior smoke particles
|
||||
for(int i=nParticles; i < iParticlesToSpawn; i++)
|
||||
{
|
||||
Vector randVec = RandomVector(-1,1);
|
||||
VectorNormalize( randVec );
|
||||
Vector endPos = vCenter + randVec * AR2_DUST_RADIUS / 4.0;
|
||||
|
||||
Vector direction = (endPos - vCenter );
|
||||
float dist = VectorNormalize( direction ) + random->RandomFloat( 0, AR2_DUST_RADIUS / 4.0 );
|
||||
if(dist > AR2_DUST_RADIUS)
|
||||
dist = AR2_DUST_RADIUS;
|
||||
|
||||
static float power = 2.0f;
|
||||
float falloffMul = pow(1.0f - dist / (AR2_DUST_RADIUS / 2), power);
|
||||
|
||||
Vector velocity = direction * AR2_DUST_SPEED * falloffMul;
|
||||
AR2ExplosionParticle *pParticle =
|
||||
(AR2ExplosionParticle*)m_ParticleEffect.AddParticle( sizeof(AR2ExplosionParticle), m_MaterialHandle );
|
||||
|
||||
if(pParticle)
|
||||
{
|
||||
pParticle->m_Pos = endPos;
|
||||
pParticle->m_Start = pParticle->m_Pos;
|
||||
pParticle->m_Dist = 8.0;
|
||||
pParticle->m_Velocity = velocity;
|
||||
// sound == 13031.496062992125984251968503937ips
|
||||
pParticle->m_Lifetime = -dist / 13031.5f - 0.1;
|
||||
pParticle->m_Roll = FRand( 0, M_PI * 2 );
|
||||
pParticle->m_RollSpeed = FRand( -1, 1 ) * 4.0;
|
||||
pParticle->m_Dwell = 0.5 * (AR2_DUST_LIFETIME + random->RandomFloat( 0, AR2_DUST_LIFETIME_DELTA ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_AR2Explosion::Update(float fTimeDelta)
|
||||
{
|
||||
if(!m_pParticleMgr)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void C_AR2Explosion::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||
{
|
||||
float dt = pIterator->GetTimeDelta();
|
||||
|
||||
AR2ExplosionParticle *pParticle = (AR2ExplosionParticle*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
if (dt > 0.05)
|
||||
dt = 0.05; // yuck, air resistance function craps out at less then 20fps
|
||||
|
||||
// Update its lifetime.
|
||||
pParticle->m_Lifetime += dt; // pDraw->GetTimeDelta();
|
||||
if(pParticle->m_Lifetime > pParticle->m_Dwell)
|
||||
{
|
||||
// faded to nothing....
|
||||
pIterator->RemoveParticle( pParticle );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Spin the thing
|
||||
pParticle->m_Roll += pParticle->m_RollSpeed * pIterator->GetTimeDelta();
|
||||
|
||||
// delayed?
|
||||
if ( pParticle->m_Lifetime >= 0.0f )
|
||||
{
|
||||
// Move it (this comes after rendering to make it clear that moving the particle here won't change
|
||||
// its rendering for this frame since m_TransformedPos has already been set).
|
||||
pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * dt;
|
||||
|
||||
// keep track of distance traveled
|
||||
pParticle->m_Dist = pParticle->m_Dist + pParticle->m_Velocity.Length() * dt;
|
||||
|
||||
// Dampen velocity.
|
||||
float dist = pParticle->m_Velocity.Length() * dt;
|
||||
float r = dist * dist;
|
||||
// FIXME: this is a really screwy air-resistance function....
|
||||
pParticle->m_Velocity = pParticle->m_Velocity * (100 / (100 + r ));
|
||||
|
||||
// dampen roll
|
||||
static float dtime;
|
||||
static float decay;
|
||||
if (dtime != dt)
|
||||
{
|
||||
dtime = dt;
|
||||
decay = ExponentialDecay( 0.3, 1.0, dtime );
|
||||
}
|
||||
if (fabs(pParticle->m_RollSpeed) > 0.2)
|
||||
pParticle->m_RollSpeed = pParticle->m_RollSpeed * decay;
|
||||
}
|
||||
}
|
||||
|
||||
pParticle = (AR2ExplosionParticle*)pIterator->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_AR2Explosion::RenderParticles( CParticleRenderIterator *pIterator )
|
||||
{
|
||||
const AR2ExplosionParticle *pParticle = (const AR2ExplosionParticle *)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
float sortKey = 0;
|
||||
if ( pParticle->m_Lifetime >= 0.0f )
|
||||
{
|
||||
// Draw.
|
||||
float lifetimePercent = ( pParticle->m_Lifetime - AR2_DUST_FADE_IN_TIME ) / pParticle->m_Dwell;
|
||||
|
||||
// FIXME: base color should be a dirty version of the material color
|
||||
Vector color = g_AR2DustColor1 * (1.0 - lifetimePercent) + g_AR2DustColor2 * lifetimePercent;
|
||||
|
||||
Vector tPos;
|
||||
TransformParticle(m_pParticleMgr->GetModelView(), pParticle->m_Pos, tPos);
|
||||
sortKey = tPos.z;
|
||||
|
||||
float alpha;
|
||||
|
||||
if ( pParticle->m_Lifetime < AR2_DUST_FADE_IN_TIME )
|
||||
{
|
||||
alpha = AR2_DUST_ALPHA * ( pParticle->m_Lifetime / AR2_DUST_FADE_IN_TIME );
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha = AR2_DUST_ALPHA * ( 1.0f - lifetimePercent );
|
||||
}
|
||||
|
||||
alpha *= GetAlphaDistanceFade( tPos, IsXbox() ? 100 : 50, IsXbox() ? 200 : 150 );
|
||||
|
||||
RenderParticle_ColorSizeAngle(
|
||||
pIterator->GetParticleDraw(),
|
||||
tPos,
|
||||
color,
|
||||
alpha,
|
||||
pParticle->m_Dist, // size based on how far it's traveled
|
||||
pParticle->m_Roll);
|
||||
}
|
||||
|
||||
pParticle = (const AR2ExplosionParticle *)pIterator->GetNext( sortKey );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
313
game/client/hl2/c_barnacle.cpp
Normal file
313
game/client/hl2/c_barnacle.cpp
Normal file
@@ -0,0 +1,313 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_ai_basenpc.h"
|
||||
#include "engine/ivmodelinfo.h"
|
||||
#include "rope_physics.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "fx_line.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "bone_setup.h"
|
||||
#include "model_types.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define BARNACLE_TONGUE_POINTS 7
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_NPC_Barnacle : public C_AI_BaseNPC
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_NPC_Barnacle, C_AI_BaseNPC );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_NPC_Barnacle( void );
|
||||
|
||||
virtual void GetRenderBounds( Vector &theMins, Vector &theMaxs )
|
||||
{
|
||||
BaseClass::GetRenderBounds( theMins, theMaxs );
|
||||
|
||||
// Extend our bounding box downwards the length of the tongue
|
||||
theMins -= Vector( 0, 0, m_flAltitude );
|
||||
}
|
||||
|
||||
// Purpose: Initialize absmin & absmax to the appropriate box
|
||||
virtual void ComputeWorldSpaceSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs )
|
||||
{
|
||||
// Extend our bounding box downwards the length of the tongue
|
||||
CollisionProp()->WorldSpaceAABB( pVecWorldMins, pVecWorldMaxs );
|
||||
|
||||
// We really care about the tongue tip. The altitude is not really relevant.
|
||||
VectorMin( *pVecWorldMins, m_vecTip, *pVecWorldMins );
|
||||
VectorMax( *pVecWorldMaxs, m_vecTip, *pVecWorldMaxs );
|
||||
|
||||
// pVecWorldMins->z -= m_flAltitude;
|
||||
}
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
void InitTonguePhysics( void );
|
||||
void ClientThink( void );
|
||||
void StandardBlendingRules( CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], float currentTime, int boneMask );
|
||||
|
||||
void SetVecTip( const float *pPosition );
|
||||
void SetAltitude( float flAltitude );
|
||||
|
||||
// Purpose:
|
||||
void ComputeVisualTipPoint( Vector *pTip );
|
||||
|
||||
protected:
|
||||
Vector m_vecTipPrevious;
|
||||
Vector m_vecRoot;
|
||||
Vector m_vecTip;
|
||||
Vector m_vecTipDrawOffset;
|
||||
|
||||
private:
|
||||
// Tongue points
|
||||
float m_flAltitude;
|
||||
Vector m_vecTonguePoints[BARNACLE_TONGUE_POINTS];
|
||||
CRopePhysics<BARNACLE_TONGUE_POINTS> m_TonguePhysics;
|
||||
|
||||
// Tongue physics delegate
|
||||
class CBarnaclePhysicsDelegate : public CSimplePhysics::IHelper
|
||||
{
|
||||
public:
|
||||
virtual void GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel );
|
||||
virtual void ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes );
|
||||
|
||||
C_NPC_Barnacle *m_pBarnacle;
|
||||
};
|
||||
friend class CBarnaclePhysicsDelegate;
|
||||
CBarnaclePhysicsDelegate m_PhysicsDelegate;
|
||||
|
||||
private:
|
||||
C_NPC_Barnacle( const C_NPC_Barnacle & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
static void RecvProxy_VecTip( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
((C_NPC_Barnacle*)pStruct)->SetVecTip( pData->m_Value.m_Vector );
|
||||
}
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_NPC_Barnacle, DT_Barnacle, CNPC_Barnacle )
|
||||
RecvPropFloat( RECVINFO( m_flAltitude ) ),
|
||||
RecvPropVector( RECVINFO( m_vecRoot ) ),
|
||||
RecvPropVector( RECVINFO( m_vecTip ), 0, RecvProxy_VecTip ),
|
||||
RecvPropVector( RECVINFO( m_vecTipDrawOffset ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_NPC_Barnacle::C_NPC_Barnacle( void )
|
||||
{
|
||||
m_PhysicsDelegate.m_pBarnacle = this;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Barnacle::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
InitTonguePhysics();
|
||||
|
||||
// We want to think every frame.
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the tongue altitude
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Barnacle::SetAltitude( float flAltitude )
|
||||
{
|
||||
m_flAltitude = flAltitude;
|
||||
}
|
||||
|
||||
void C_NPC_Barnacle::SetVecTip( const float *pPosition )
|
||||
{
|
||||
Vector vecNewTip;
|
||||
vecNewTip.Init( pPosition[0], pPosition[1], pPosition[2] );
|
||||
if ( vecNewTip != m_vecTip )
|
||||
{
|
||||
m_vecTip = vecNewTip;
|
||||
CollisionProp()->MarkSurroundingBoundsDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Barnacle::InitTonguePhysics( void )
|
||||
{
|
||||
// Init tongue spline
|
||||
// First point is at the top
|
||||
m_TonguePhysics.SetupSimulation( m_flAltitude / (BARNACLE_TONGUE_POINTS-1), &m_PhysicsDelegate );
|
||||
m_TonguePhysics.Restart();
|
||||
|
||||
// Initialize the positions of the nodes.
|
||||
m_TonguePhysics.GetFirstNode()->m_vPos = m_vecRoot;
|
||||
m_TonguePhysics.GetFirstNode()->m_vPrevPos = m_TonguePhysics.GetFirstNode()->m_vPos;
|
||||
float flAltitude = m_flAltitude;
|
||||
for( int i = 1; i < m_TonguePhysics.NumNodes(); i++ )
|
||||
{
|
||||
flAltitude *= 0.5;
|
||||
CSimplePhysics::CNode *pNode = m_TonguePhysics.GetNode( i );
|
||||
pNode->m_vPos = m_TonguePhysics.GetNode(i-1)->m_vPos - Vector(0,0,flAltitude);
|
||||
pNode->m_vPrevPos = pNode->m_vPos;
|
||||
|
||||
// Set the length of the node's spring
|
||||
//m_TonguePhysics.ResetNodeSpringLength( i-1, flAltitude );
|
||||
}
|
||||
|
||||
m_vecTipPrevious = m_vecTip;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Barnacle::ClientThink( void )
|
||||
{
|
||||
m_TonguePhysics.Simulate( gpGlobals->frametime );
|
||||
|
||||
// Set the spring's length to that of the tongue's extension
|
||||
m_TonguePhysics.ResetSpringLength( m_flAltitude / (BARNACLE_TONGUE_POINTS-1) );
|
||||
|
||||
// Necessary because ComputeVisualTipPoint depends on m_vecTipPrevious
|
||||
Vector vecTemp;
|
||||
ComputeVisualTipPoint( &vecTemp );
|
||||
m_vecTipPrevious = vecTemp;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Barnacle::StandardBlendingRules( CStudioHdr *hdr, Vector pos[], Quaternion q[], float currentTime, int boneMask )
|
||||
{
|
||||
BaseClass::StandardBlendingRules( hdr, pos, q, currentTime, boneMask );
|
||||
|
||||
if ( !hdr )
|
||||
return;
|
||||
|
||||
int firstBone = Studio_BoneIndexByName( hdr, "Barnacle.tongue1" );
|
||||
|
||||
Vector vecPrevRight;
|
||||
GetVectors( NULL, &vecPrevRight, NULL );
|
||||
|
||||
Vector vecPrev = pos[Studio_BoneIndexByName( hdr, "Barnacle.base" )];
|
||||
Vector vecCurr = vec3_origin;
|
||||
Vector vecForward;
|
||||
for ( int i = 0; i <= BARNACLE_TONGUE_POINTS; i++ )
|
||||
{
|
||||
// We double up the bones at the last node.
|
||||
if ( i == BARNACLE_TONGUE_POINTS )
|
||||
{
|
||||
vecCurr = m_TonguePhysics.GetLastNode()->m_vPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
vecCurr = m_TonguePhysics.GetNode(i)->m_vPos;
|
||||
}
|
||||
|
||||
//debugoverlay->AddBoxOverlay( vecCurr, -Vector(2,2,2), Vector(2,2,2), vec3_angle, 0,255,0, 128, 0.1 );
|
||||
|
||||
// Fill out the positions in local space
|
||||
VectorITransform( vecCurr, EntityToWorldTransform(), pos[firstBone+i] );
|
||||
vecCurr = pos[firstBone+i];
|
||||
|
||||
// Disallow twist in the tongue visually
|
||||
// Forward vector has to follow the tongue, right + up have to minimize twist from
|
||||
// the previous bone
|
||||
|
||||
// Fill out the angles
|
||||
if ( i != BARNACLE_TONGUE_POINTS )
|
||||
{
|
||||
vecForward = (vecCurr - vecPrev);
|
||||
if ( VectorNormalize( vecForward ) < 1e-3 )
|
||||
{
|
||||
vecForward.Init( 0, 0, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
// Project the previous vecRight into a plane perpendicular to vecForward
|
||||
// that's the vector closest to what we want...
|
||||
Vector vecRight, vecUp;
|
||||
VectorMA( vecPrevRight, -DotProduct( vecPrevRight, vecForward ), vecForward, vecRight );
|
||||
VectorNormalize( vecRight );
|
||||
CrossProduct( vecForward, vecRight, vecUp );
|
||||
|
||||
BasisToQuaternion( vecForward, vecRight, vecUp, q[firstBone+i] );
|
||||
|
||||
vecPrev = vecCurr;
|
||||
vecPrevRight = vecRight;
|
||||
}
|
||||
}
|
||||
|
||||
//===============================================================================================================================
|
||||
// BARNACLE TONGUE PHYSICS
|
||||
//===============================================================================================================================
|
||||
#define TONGUE_GRAVITY 0, 0, -1000
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Barnacle::CBarnaclePhysicsDelegate::GetNodeForces( CSimplePhysics::CNode *pNodes, int iNode, Vector *pAccel )
|
||||
{
|
||||
// Gravity.
|
||||
pAccel->Init( TONGUE_GRAVITY );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
#define TIP_SNAP_FACTOR 200
|
||||
// Todo: this really ought to be SIMD.
|
||||
void C_NPC_Barnacle::ComputeVisualTipPoint( Vector *pTip )
|
||||
{
|
||||
float flTipMove = TIP_SNAP_FACTOR * gpGlobals->frametime;
|
||||
Vector tipIdeal;
|
||||
VectorAdd(m_vecTip, m_vecTipDrawOffset, tipIdeal);
|
||||
if ( tipIdeal.DistToSqr( m_vecTipPrevious ) > (flTipMove * flTipMove) )
|
||||
{
|
||||
// Inch the visual tip toward the actual tip
|
||||
VectorSubtract( tipIdeal, m_vecTipPrevious, *pTip );
|
||||
VectorNormalize( *pTip );
|
||||
*pTip *= flTipMove;
|
||||
*pTip += m_vecTipPrevious;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pTip = tipIdeal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Barnacle::CBarnaclePhysicsDelegate::ApplyConstraints( CSimplePhysics::CNode *pNodes, int nNodes )
|
||||
{
|
||||
// Startpoint always stays at the root
|
||||
pNodes[0].m_vPos = m_pBarnacle->m_vecRoot;
|
||||
|
||||
// Endpoint always stays at the tip
|
||||
m_pBarnacle->ComputeVisualTipPoint( &pNodes[nNodes-1].m_vPos );
|
||||
}
|
||||
41
game/client/hl2/c_barney.cpp
Normal file
41
game/client/hl2/c_barney.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_ai_basenpc.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_Barney : public C_AI_BaseNPC
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_Barney, C_AI_BaseNPC );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_Barney();
|
||||
virtual ~C_Barney();
|
||||
|
||||
private:
|
||||
C_Barney( const C_Barney & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_Barney, DT_NPC_Barney, CNPC_Barney)
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_Barney::C_Barney()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
C_Barney::~C_Barney()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
91
game/client/hl2/c_basehelicopter.cpp
Normal file
91
game/client/hl2/c_basehelicopter.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_basehelicopter.h"
|
||||
#include "proxyentity.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "KeyValues.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BaseHelicopter, DT_BaseHelicopter, CBaseHelicopter )
|
||||
RecvPropTime( RECVINFO( m_flStartupTime ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
C_BaseHelicopter::C_BaseHelicopter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Chopper blade fade-in time
|
||||
//-----------------------------------------------------------------------------
|
||||
#define FADE_IN_TIME 2.0f
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sets the fade of the blades when the chopper starts up
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHeliBladeMaterialProxy : public CEntityMaterialProxy
|
||||
{
|
||||
public:
|
||||
CHeliBladeMaterialProxy() { m_AlphaVar = NULL; }
|
||||
virtual ~CHeliBladeMaterialProxy() {}
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( C_BaseEntity *pEntity );
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
private:
|
||||
IMaterialVar *m_AlphaVar;
|
||||
bool m_bFadeOut;
|
||||
};
|
||||
|
||||
bool CHeliBladeMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
bool foundVar;
|
||||
m_AlphaVar = pMaterial->FindVar( "$alpha", &foundVar, false );
|
||||
m_bFadeOut = pKeyValues->GetInt( "$fadeout", 0 ) != 0;
|
||||
return foundVar;
|
||||
}
|
||||
|
||||
void CHeliBladeMaterialProxy::OnBind( C_BaseEntity *pEnt )
|
||||
{
|
||||
if (!m_AlphaVar)
|
||||
return;
|
||||
|
||||
C_BaseHelicopter *pHeli = dynamic_cast<C_BaseHelicopter*>( pEnt );
|
||||
if ( pHeli )
|
||||
{
|
||||
float dt = gpGlobals->curtime - pHeli->StartupTime();
|
||||
dt /= FADE_IN_TIME;
|
||||
dt = clamp( dt, 0.0f, 1.0f );
|
||||
if ( m_bFadeOut )
|
||||
{
|
||||
dt = 1.0f - dt;
|
||||
}
|
||||
|
||||
m_AlphaVar->SetFloatValue( dt );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_AlphaVar->SetFloatValue( 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
IMaterial *CHeliBladeMaterialProxy::GetMaterial()
|
||||
{
|
||||
if ( !m_AlphaVar )
|
||||
return NULL;
|
||||
|
||||
return m_AlphaVar->GetOwningMaterial();
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CHeliBladeMaterialProxy, IMaterialProxy, "HeliBlade" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
|
||||
33
game/client/hl2/c_basehelicopter.h
Normal file
33
game/client/hl2/c_basehelicopter.h
Normal file
@@ -0,0 +1,33 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef C_BASEHELICOPTER_H
|
||||
#define C_BASEHELICOPTER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_ai_basenpc.h"
|
||||
|
||||
|
||||
class C_BaseHelicopter : public C_AI_BaseNPC
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseHelicopter, C_AI_BaseNPC );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_BaseHelicopter();
|
||||
|
||||
float StartupTime() const { return m_flStartupTime; }
|
||||
|
||||
private:
|
||||
C_BaseHelicopter( const C_BaseHelicopter &other ) {}
|
||||
float m_flStartupTime;
|
||||
};
|
||||
|
||||
|
||||
#endif // C_BASEHELICOPTER_H
|
||||
21
game/client/hl2/c_basehlcombatweapon.cpp
Normal file
21
game/client/hl2/c_basehlcombatweapon.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_basehlcombatweapon.h"
|
||||
#include "igamemovement.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_HLMachineGun, DT_HLMachineGun, CHLMachineGun )
|
||||
END_RECV_TABLE()
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_HLSelectFireMachineGun, DT_HLSelectFireMachineGun, CHLSelectFireMachineGun )
|
||||
END_RECV_TABLE()
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_BaseHLBludgeonWeapon, DT_BaseHLBludgeonWeapon, CBaseHLBludgeonWeapon )
|
||||
END_RECV_TABLE()
|
||||
36
game/client/hl2/c_basehlcombatweapon.h
Normal file
36
game/client/hl2/c_basehlcombatweapon.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "basehlcombatweapon_shared.h"
|
||||
|
||||
#ifndef C_BASEHLCOMBATWEAPON_H
|
||||
#define C_BASEHLCOMBATWEAPON_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class C_HLMachineGun : public C_BaseHLCombatWeapon
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_HLMachineGun, C_BaseHLCombatWeapon );
|
||||
DECLARE_CLIENTCLASS();
|
||||
};
|
||||
|
||||
class C_HLSelectFireMachineGun : public C_HLMachineGun
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_HLSelectFireMachineGun, C_HLMachineGun );
|
||||
DECLARE_CLIENTCLASS();
|
||||
};
|
||||
|
||||
class C_BaseHLBludgeonWeapon : public C_BaseHLCombatWeapon
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseHLBludgeonWeapon, C_BaseHLCombatWeapon );
|
||||
DECLARE_CLIENTCLASS();
|
||||
};
|
||||
|
||||
#endif // C_BASEHLCOMBATWEAPON_H
|
||||
649
game/client/hl2/c_basehlplayer.cpp
Normal file
649
game/client/hl2/c_basehlplayer.cpp
Normal file
@@ -0,0 +1,649 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basehlplayer.h"
|
||||
#include "playerandobjectenumerator.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "c_ai_basenpc.h"
|
||||
#include "in_buttons.h"
|
||||
#include "collisionutils.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// How fast to avoid collisions with center of other object, in units per second
|
||||
#define AVOID_SPEED 2000.0f
|
||||
extern ConVar cl_forwardspeed;
|
||||
extern ConVar cl_backspeed;
|
||||
extern ConVar cl_sidespeed;
|
||||
|
||||
extern ConVar zoom_sensitivity_ratio;
|
||||
extern ConVar default_fov;
|
||||
extern ConVar sensitivity;
|
||||
|
||||
ConVar cl_npc_speedmod_intime( "cl_npc_speedmod_intime", "0.25", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
|
||||
ConVar cl_npc_speedmod_outtime( "cl_npc_speedmod_outtime", "1.5", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_BaseHLPlayer, DT_HL2_Player, CHL2_Player)
|
||||
RecvPropDataTable( RECVINFO_DT(m_HL2Local),0, &REFERENCE_RECV_TABLE(DT_HL2Local) ),
|
||||
RecvPropBool( RECVINFO( m_fIsSprinting ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA( C_BaseHLPlayer )
|
||||
DEFINE_PRED_TYPEDESCRIPTION( m_HL2Local, C_HL2PlayerLocalData ),
|
||||
DEFINE_PRED_FIELD( m_fIsSprinting, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Drops player's primary weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
void CC_DropPrimary( void )
|
||||
{
|
||||
C_BasePlayer *pPlayer = (C_BasePlayer *) C_BasePlayer::GetLocalPlayer();
|
||||
|
||||
if ( pPlayer == NULL )
|
||||
return;
|
||||
|
||||
pPlayer->Weapon_DropPrimary();
|
||||
}
|
||||
|
||||
static ConCommand dropprimary("dropprimary", CC_DropPrimary, "dropprimary: Drops the primary weapon of the player.");
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseHLPlayer::C_BaseHLPlayer()
|
||||
{
|
||||
AddVar( &m_Local.m_vecPunchAngle, &m_Local.m_iv_vecPunchAngle, LATCH_SIMULATION_VAR );
|
||||
AddVar( &m_Local.m_vecPunchAngleVel, &m_Local.m_iv_vecPunchAngleVel, LATCH_SIMULATION_VAR );
|
||||
|
||||
m_flZoomStart = 0.0f;
|
||||
m_flZoomEnd = 0.0f;
|
||||
m_flZoomRate = 0.0f;
|
||||
m_flZoomStartTime = 0.0f;
|
||||
m_flSpeedMod = cl_forwardspeed.GetFloat();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseHLPlayer::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
// Make sure we're thinking
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseHLPlayer::Weapon_DropPrimary( void )
|
||||
{
|
||||
engine->ServerCmd( "DropPrimary" );
|
||||
}
|
||||
|
||||
float C_BaseHLPlayer::GetFOV()
|
||||
{
|
||||
//Find our FOV with offset zoom value
|
||||
float flFOVOffset = BaseClass::GetFOV() + GetZoom();
|
||||
|
||||
// Clamp FOV in MP
|
||||
int min_fov = ( gpGlobals->maxClients == 1 ) ? 5 : default_fov.GetInt();
|
||||
|
||||
// Don't let it go too low
|
||||
flFOVOffset = MAX( min_fov, flFOVOffset );
|
||||
|
||||
return flFOVOffset;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float C_BaseHLPlayer::GetZoom( void )
|
||||
{
|
||||
float fFOV = m_flZoomEnd;
|
||||
|
||||
//See if we need to lerp the values
|
||||
if ( ( m_flZoomStart != m_flZoomEnd ) && ( m_flZoomRate > 0.0f ) )
|
||||
{
|
||||
float deltaTime = (float)( gpGlobals->curtime - m_flZoomStartTime ) / m_flZoomRate;
|
||||
|
||||
if ( deltaTime >= 1.0f )
|
||||
{
|
||||
//If we're past the zoom time, just take the new value and stop lerping
|
||||
fFOV = m_flZoomStart = m_flZoomEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
fFOV = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, m_flZoomStart, m_flZoomEnd );
|
||||
}
|
||||
}
|
||||
|
||||
return fFOV;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : FOVOffset -
|
||||
// time -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseHLPlayer::Zoom( float FOVOffset, float time )
|
||||
{
|
||||
m_flZoomStart = GetZoom();
|
||||
m_flZoomEnd = FOVOffset;
|
||||
m_flZoomRate = time;
|
||||
m_flZoomStartTime = gpGlobals->curtime;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Hack to zero out player's pitch, use value from poseparameter instead
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_BaseHLPlayer::DrawModel( int flags )
|
||||
{
|
||||
// Not pitch for player
|
||||
QAngle saveAngles = GetLocalAngles();
|
||||
|
||||
QAngle useAngles = saveAngles;
|
||||
useAngles[ PITCH ] = 0.0f;
|
||||
|
||||
SetLocalAngles( useAngles );
|
||||
|
||||
int iret = BaseClass::DrawModel( flags );
|
||||
|
||||
SetLocalAngles( saveAngles );
|
||||
|
||||
return iret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Helper to remove from ladder
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseHLPlayer::ExitLadder()
|
||||
{
|
||||
if ( MOVETYPE_LADDER != GetMoveType() )
|
||||
return;
|
||||
|
||||
SetMoveType( MOVETYPE_WALK );
|
||||
SetMoveCollide( MOVECOLLIDE_DEFAULT );
|
||||
// Remove from ladder
|
||||
m_HL2Local.m_hLadder = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Determines if a player can be safely moved towards a point
|
||||
// Input: pos - position to test move to, fVertDist - how far to trace downwards to see if the player would fall,
|
||||
// radius - how close the player can be to the object, objPos - position of the object to avoid,
|
||||
// objDir - direction the object is travelling
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseHLPlayer::TestMove( const Vector &pos, float fVertDist, float radius, const Vector &objPos, const Vector &objDir )
|
||||
{
|
||||
trace_t trUp;
|
||||
trace_t trOver;
|
||||
trace_t trDown;
|
||||
float flHit1, flHit2;
|
||||
|
||||
UTIL_TraceHull( GetAbsOrigin(), pos, GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver );
|
||||
if ( trOver.fraction < 1.0f )
|
||||
{
|
||||
// check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move.
|
||||
if ( objDir.IsZero() ||
|
||||
( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) &&
|
||||
( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) )
|
||||
)
|
||||
{
|
||||
// our first trace failed, so see if we can go farther if we step up.
|
||||
|
||||
// trace up to see if we have enough room.
|
||||
UTIL_TraceHull( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, m_Local.m_flStepSize ),
|
||||
GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trUp );
|
||||
|
||||
// do a trace from the stepped up height
|
||||
UTIL_TraceHull( trUp.endpos, pos + Vector( 0, 0, trUp.endpos.z - trUp.startpos.z ),
|
||||
GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver );
|
||||
|
||||
if ( trOver.fraction < 1.0f )
|
||||
{
|
||||
// check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move.
|
||||
if ( objDir.IsZero() ||
|
||||
( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) && ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// trace down to see if this position is on the ground
|
||||
UTIL_TraceLine( trOver.endpos, trOver.endpos - Vector( 0, 0, fVertDist ),
|
||||
MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &trDown );
|
||||
|
||||
if ( trDown.fraction == 1.0f )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Client-side obstacle avoidance
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseHLPlayer::PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd )
|
||||
{
|
||||
// Don't avoid if noclipping or in movetype none
|
||||
switch ( GetMoveType() )
|
||||
{
|
||||
case MOVETYPE_NOCLIP:
|
||||
case MOVETYPE_NONE:
|
||||
case MOVETYPE_OBSERVER:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Try to steer away from any objects/players we might interpenetrate
|
||||
Vector size = WorldAlignSize();
|
||||
|
||||
float radius = 0.7f * sqrt( size.x * size.x + size.y * size.y );
|
||||
float curspeed = GetLocalVelocity().Length2D();
|
||||
|
||||
//int slot = 1;
|
||||
//engine->Con_NPrintf( slot++, "speed %f\n", curspeed );
|
||||
//engine->Con_NPrintf( slot++, "radius %f\n", radius );
|
||||
|
||||
// If running, use a larger radius
|
||||
float factor = 1.0f;
|
||||
|
||||
if ( curspeed > 150.0f )
|
||||
{
|
||||
curspeed = MIN( 2048.0f, curspeed );
|
||||
factor = ( 1.0f + ( curspeed - 150.0f ) / 150.0f );
|
||||
|
||||
//engine->Con_NPrintf( slot++, "scaleup (%f) to radius %f\n", factor, radius * factor );
|
||||
|
||||
radius = radius * factor;
|
||||
}
|
||||
|
||||
Vector currentdir;
|
||||
Vector rightdir;
|
||||
|
||||
QAngle vAngles = pCmd->viewangles;
|
||||
vAngles.x = 0;
|
||||
|
||||
AngleVectors( vAngles, ¤tdir, &rightdir, NULL );
|
||||
|
||||
bool istryingtomove = false;
|
||||
bool ismovingforward = false;
|
||||
if ( fabs( pCmd->forwardmove ) > 0.0f ||
|
||||
fabs( pCmd->sidemove ) > 0.0f )
|
||||
{
|
||||
istryingtomove = true;
|
||||
if ( pCmd->forwardmove > 1.0f )
|
||||
{
|
||||
ismovingforward = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( istryingtomove == true )
|
||||
radius *= 1.3f;
|
||||
|
||||
CPlayerAndObjectEnumerator avoid( radius );
|
||||
partition->EnumerateElementsInSphere( PARTITION_CLIENT_SOLID_EDICTS, GetAbsOrigin(), radius, false, &avoid );
|
||||
|
||||
// Okay, decide how to avoid if there's anything close by
|
||||
int c = avoid.GetObjectCount();
|
||||
if ( c <= 0 )
|
||||
return;
|
||||
|
||||
//engine->Con_NPrintf( slot++, "moving %s forward %s\n", istryingtomove ? "true" : "false", ismovingforward ? "true" : "false" );
|
||||
|
||||
float adjustforwardmove = 0.0f;
|
||||
float adjustsidemove = 0.0f;
|
||||
|
||||
for ( int i = 0; i < c; i++ )
|
||||
{
|
||||
C_AI_BaseNPC *obj = dynamic_cast< C_AI_BaseNPC *>(avoid.GetObject( i ));
|
||||
|
||||
if( !obj )
|
||||
continue;
|
||||
|
||||
Vector vecToObject = obj->GetAbsOrigin() - GetAbsOrigin();
|
||||
|
||||
float flDist = vecToObject.Length2D();
|
||||
|
||||
// Figure out a 2D radius for the object
|
||||
Vector vecWorldMins, vecWorldMaxs;
|
||||
obj->CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs );
|
||||
Vector objSize = vecWorldMaxs - vecWorldMins;
|
||||
|
||||
float objectradius = 0.5f * sqrt( objSize.x * objSize.x + objSize.y * objSize.y );
|
||||
|
||||
//Don't run this code if the NPC is not moving UNLESS we are in stuck inside of them.
|
||||
if ( !obj->IsMoving() && flDist > objectradius )
|
||||
continue;
|
||||
|
||||
if ( flDist > objectradius && obj->IsEffectActive( EF_NODRAW ) )
|
||||
{
|
||||
obj->RemoveEffects( EF_NODRAW );
|
||||
}
|
||||
|
||||
Vector vecNPCVelocity;
|
||||
obj->EstimateAbsVelocity( vecNPCVelocity );
|
||||
float flNPCSpeed = VectorNormalize( vecNPCVelocity );
|
||||
|
||||
Vector vPlayerVel = GetAbsVelocity();
|
||||
VectorNormalize( vPlayerVel );
|
||||
|
||||
float flHit1, flHit2;
|
||||
Vector vRayDir = vecToObject;
|
||||
VectorNormalize( vRayDir );
|
||||
|
||||
float flVelProduct = DotProduct( vecNPCVelocity, vPlayerVel );
|
||||
float flDirProduct = DotProduct( vRayDir, vPlayerVel );
|
||||
|
||||
if ( !IntersectInfiniteRayWithSphere(
|
||||
GetAbsOrigin(),
|
||||
vRayDir,
|
||||
obj->GetAbsOrigin(),
|
||||
radius,
|
||||
&flHit1,
|
||||
&flHit2 ) )
|
||||
continue;
|
||||
|
||||
Vector dirToObject = -vecToObject;
|
||||
VectorNormalize( dirToObject );
|
||||
|
||||
float fwd = 0;
|
||||
float rt = 0;
|
||||
|
||||
float sidescale = 2.0f;
|
||||
float forwardscale = 1.0f;
|
||||
bool foundResult = false;
|
||||
|
||||
Vector vMoveDir = vecNPCVelocity;
|
||||
if ( flNPCSpeed > 0.001f )
|
||||
{
|
||||
// This NPC is moving. First try deflecting the player left or right relative to the NPC's velocity.
|
||||
// Start with whatever side they're on relative to the NPC's velocity.
|
||||
Vector vecNPCTrajectoryRight = CrossProduct( vecNPCVelocity, Vector( 0, 0, 1) );
|
||||
int iDirection = ( vecNPCTrajectoryRight.Dot( dirToObject ) > 0 ) ? 1 : -1;
|
||||
for ( int nTries = 0; nTries < 2; nTries++ )
|
||||
{
|
||||
Vector vecTryMove = vecNPCTrajectoryRight * iDirection;
|
||||
VectorNormalize( vecTryMove );
|
||||
|
||||
Vector vTestPosition = GetAbsOrigin() + vecTryMove * radius * 2;
|
||||
|
||||
if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
|
||||
{
|
||||
fwd = currentdir.Dot( vecTryMove );
|
||||
rt = rightdir.Dot( vecTryMove );
|
||||
|
||||
//Msg( "PUSH DEFLECT fwd=%f, rt=%f\n", fwd, rt );
|
||||
|
||||
foundResult = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try the other direction.
|
||||
iDirection *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// the object isn't moving, so try moving opposite the way it's facing
|
||||
Vector vecNPCForward;
|
||||
obj->GetVectors( &vecNPCForward, NULL, NULL );
|
||||
|
||||
Vector vTestPosition = GetAbsOrigin() - vecNPCForward * radius * 2;
|
||||
if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
|
||||
{
|
||||
fwd = currentdir.Dot( -vecNPCForward );
|
||||
rt = rightdir.Dot( -vecNPCForward );
|
||||
|
||||
if ( flDist < objectradius )
|
||||
{
|
||||
obj->AddEffects( EF_NODRAW );
|
||||
}
|
||||
|
||||
//Msg( "PUSH AWAY FACE fwd=%f, rt=%f\n", fwd, rt );
|
||||
|
||||
foundResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !foundResult )
|
||||
{
|
||||
// test if we can move in the direction the object is moving
|
||||
Vector vTestPosition = GetAbsOrigin() + vMoveDir * radius * 2;
|
||||
if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
|
||||
{
|
||||
fwd = currentdir.Dot( vMoveDir );
|
||||
rt = rightdir.Dot( vMoveDir );
|
||||
|
||||
if ( flDist < objectradius )
|
||||
{
|
||||
obj->AddEffects( EF_NODRAW );
|
||||
}
|
||||
|
||||
//Msg( "PUSH ALONG fwd=%f, rt=%f\n", fwd, rt );
|
||||
|
||||
foundResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// try moving directly away from the object
|
||||
Vector vTestPosition = GetAbsOrigin() - dirToObject * radius * 2;
|
||||
if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) )
|
||||
{
|
||||
fwd = currentdir.Dot( -dirToObject );
|
||||
rt = rightdir.Dot( -dirToObject );
|
||||
foundResult = true;
|
||||
|
||||
//Msg( "PUSH AWAY fwd=%f, rt=%f\n", fwd, rt );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !foundResult )
|
||||
{
|
||||
// test if we can move through the object
|
||||
Vector vTestPosition = GetAbsOrigin() - vMoveDir * radius * 2;
|
||||
fwd = currentdir.Dot( -vMoveDir );
|
||||
rt = rightdir.Dot( -vMoveDir );
|
||||
|
||||
if ( flDist < objectradius )
|
||||
{
|
||||
obj->AddEffects( EF_NODRAW );
|
||||
}
|
||||
|
||||
//Msg( "PUSH THROUGH fwd=%f, rt=%f\n", fwd, rt );
|
||||
|
||||
foundResult = true;
|
||||
}
|
||||
|
||||
// If running, then do a lot more sideways veer since we're not going to do anything to
|
||||
// forward velocity
|
||||
if ( istryingtomove )
|
||||
{
|
||||
sidescale = 6.0f;
|
||||
}
|
||||
|
||||
if ( flVelProduct > 0.0f && flDirProduct > 0.0f )
|
||||
{
|
||||
sidescale = 0.1f;
|
||||
}
|
||||
|
||||
float force = 1.0f;
|
||||
float forward = forwardscale * fwd * force * AVOID_SPEED;
|
||||
float side = sidescale * rt * force * AVOID_SPEED;
|
||||
|
||||
adjustforwardmove += forward;
|
||||
adjustsidemove += side;
|
||||
}
|
||||
|
||||
pCmd->forwardmove += adjustforwardmove;
|
||||
pCmd->sidemove += adjustsidemove;
|
||||
|
||||
// Clamp the move to within legal limits, preserving direction. This is a little
|
||||
// complicated because we have different limits for forward, back, and side
|
||||
|
||||
//Msg( "PRECLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
|
||||
|
||||
float flForwardScale = 1.0f;
|
||||
if ( pCmd->forwardmove > fabs( cl_forwardspeed.GetFloat() ) )
|
||||
{
|
||||
flForwardScale = fabs( cl_forwardspeed.GetFloat() ) / pCmd->forwardmove;
|
||||
}
|
||||
else if ( pCmd->forwardmove < -fabs( cl_backspeed.GetFloat() ) )
|
||||
{
|
||||
flForwardScale = fabs( cl_backspeed.GetFloat() ) / fabs( pCmd->forwardmove );
|
||||
}
|
||||
|
||||
float flSideScale = 1.0f;
|
||||
if ( fabs( pCmd->sidemove ) > fabs( cl_sidespeed.GetFloat() ) )
|
||||
{
|
||||
flSideScale = fabs( cl_sidespeed.GetFloat() ) / fabs( pCmd->sidemove );
|
||||
}
|
||||
|
||||
float flScale = MIN( flForwardScale, flSideScale );
|
||||
pCmd->forwardmove *= flScale;
|
||||
pCmd->sidemove *= flScale;
|
||||
|
||||
//Msg( "POSTCLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove );
|
||||
}
|
||||
|
||||
|
||||
void C_BaseHLPlayer::PerformClientSideNPCSpeedModifiers( float flFrameTime, CUserCmd *pCmd )
|
||||
{
|
||||
if ( m_hClosestNPC == NULL )
|
||||
{
|
||||
if ( m_flSpeedMod != cl_forwardspeed.GetFloat() )
|
||||
{
|
||||
float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
|
||||
m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_outtime.GetFloat(), 0, m_flExitSpeedMod, cl_forwardspeed.GetFloat() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
C_AI_BaseNPC *pNPC = dynamic_cast< C_AI_BaseNPC *>( m_hClosestNPC.Get() );
|
||||
|
||||
if ( pNPC )
|
||||
{
|
||||
float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr();
|
||||
bool bShouldModSpeed = false;
|
||||
|
||||
// Within range?
|
||||
if ( flDist < pNPC->GetSpeedModifyRadius() )
|
||||
{
|
||||
// Now, only slowdown if we're facing & running parallel to the target's movement
|
||||
// Facing check first (in 2D)
|
||||
Vector vecTargetOrigin = pNPC->GetAbsOrigin();
|
||||
Vector los = ( vecTargetOrigin - EyePosition() );
|
||||
los.z = 0;
|
||||
VectorNormalize( los );
|
||||
Vector facingDir;
|
||||
AngleVectors( GetAbsAngles(), &facingDir );
|
||||
float flDot = DotProduct( los, facingDir );
|
||||
if ( flDot > 0.8 )
|
||||
{
|
||||
/*
|
||||
// Velocity check (abort if the target isn't moving)
|
||||
Vector vecTargetVelocity;
|
||||
pNPC->EstimateAbsVelocity( vecTargetVelocity );
|
||||
float flSpeed = VectorNormalize(vecTargetVelocity);
|
||||
Vector vecMyVelocity = GetAbsVelocity();
|
||||
VectorNormalize(vecMyVelocity);
|
||||
if ( flSpeed > 1.0 )
|
||||
{
|
||||
// Velocity roughly parallel?
|
||||
if ( DotProduct(vecTargetVelocity,vecMyVelocity) > 0.4 )
|
||||
{
|
||||
bShouldModSpeed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// NPC's not moving, slow down if we're moving at him
|
||||
//Msg("Dot: %.2f\n", DotProduct( los, vecMyVelocity ) );
|
||||
if ( DotProduct( los, vecMyVelocity ) > 0.8 )
|
||||
{
|
||||
bShouldModSpeed = true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
bShouldModSpeed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bShouldModSpeed )
|
||||
{
|
||||
m_hClosestNPC = NULL;
|
||||
m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_outtime.GetFloat();
|
||||
m_flExitSpeedMod = m_flSpeedMod;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_flSpeedMod != pNPC->GetSpeedModifySpeed() )
|
||||
{
|
||||
float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime);
|
||||
m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_intime.GetFloat(), 0, cl_forwardspeed.GetFloat(), pNPC->GetSpeedModifySpeed() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( pCmd->forwardmove > 0.0f )
|
||||
{
|
||||
pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
|
||||
}
|
||||
else
|
||||
{
|
||||
pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod );
|
||||
}
|
||||
pCmd->sidemove = clamp( pCmd->sidemove, -m_flSpeedMod, m_flSpeedMod );
|
||||
|
||||
//Msg( "fwd %f right %f\n", pCmd->forwardmove, pCmd->sidemove );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Input handling
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_BaseHLPlayer::CreateMove( float flInputSampleTime, CUserCmd *pCmd )
|
||||
{
|
||||
bool bResult = BaseClass::CreateMove( flInputSampleTime, pCmd );
|
||||
|
||||
if ( !IsInAVehicle() )
|
||||
{
|
||||
PerformClientSideObstacleAvoidance( TICK_INTERVAL, pCmd );
|
||||
PerformClientSideNPCSpeedModifiers( TICK_INTERVAL, pCmd );
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Input handling
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_BaseHLPlayer::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
|
||||
{
|
||||
BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed );
|
||||
BuildFirstPersonMeathookTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed, "ValveBiped.Bip01_Head1" );
|
||||
}
|
||||
|
||||
81
game/client/hl2/c_basehlplayer.h
Normal file
81
game/client/hl2/c_basehlplayer.h
Normal file
@@ -0,0 +1,81 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#if !defined( C_BASEHLPLAYER_H )
|
||||
#define C_BASEHLPLAYER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "c_baseplayer.h"
|
||||
#include "c_hl2_playerlocaldata.h"
|
||||
|
||||
class C_BaseHLPlayer : public C_BasePlayer
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_BaseHLPlayer, C_BasePlayer );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
C_BaseHLPlayer();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
|
||||
void Weapon_DropPrimary( void );
|
||||
|
||||
float GetFOV();
|
||||
void Zoom( float FOVOffset, float time );
|
||||
float GetZoom( void );
|
||||
bool IsZoomed( void ) { return m_HL2Local.m_bZooming; }
|
||||
|
||||
bool IsSprinting( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_SPRINT; }
|
||||
bool IsFlashlightActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_FLASHLIGHT; }
|
||||
bool IsBreatherActive( void ) { return m_HL2Local.m_bitsActiveDevices & bits_SUIT_DEVICE_BREATHER; }
|
||||
|
||||
virtual int DrawModel( int flags );
|
||||
virtual void BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed );
|
||||
|
||||
LadderMove_t *GetLadderMove() { return &m_HL2Local.m_LadderMove; }
|
||||
virtual void ExitLadder();
|
||||
bool IsSprinting() const { return m_fIsSprinting; }
|
||||
|
||||
// Input handling
|
||||
virtual bool CreateMove( float flInputSampleTime, CUserCmd *pCmd );
|
||||
void PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd );
|
||||
void PerformClientSideNPCSpeedModifiers( float flFrameTime, CUserCmd *pCmd );
|
||||
|
||||
bool IsWeaponLowered( void ) { return m_HL2Local.m_bWeaponLowered; }
|
||||
|
||||
public:
|
||||
|
||||
C_HL2PlayerLocalData m_HL2Local;
|
||||
EHANDLE m_hClosestNPC;
|
||||
float m_flSpeedModTime;
|
||||
bool m_fIsSprinting;
|
||||
|
||||
private:
|
||||
C_BaseHLPlayer( const C_BaseHLPlayer & ); // not defined, not accessible
|
||||
|
||||
bool TestMove( const Vector &pos, float fVertDist, float radius, const Vector &objPos, const Vector &objDir );
|
||||
|
||||
float m_flZoomStart;
|
||||
float m_flZoomEnd;
|
||||
float m_flZoomRate;
|
||||
float m_flZoomStartTime;
|
||||
|
||||
bool m_bPlayUseDenySound; // Signaled by PlayerUse, but can be unset by HL2 ladder code...
|
||||
float m_flSpeedMod;
|
||||
float m_flExitSpeedMod;
|
||||
|
||||
|
||||
friend class CHL2GameMovement;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
483
game/client/hl2/c_citadel_effects.cpp
Normal file
483
game/client/hl2/c_citadel_effects.cpp
Normal file
@@ -0,0 +1,483 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "particles_simple.h"
|
||||
#include "citadel_effects_shared.h"
|
||||
#include "particles_attractor.h"
|
||||
#include "fx_quad.h"
|
||||
|
||||
class C_CitadelEnergyCore : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_CitadelEnergyCore, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
public:
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
RenderGroup_t GetRenderGroup( void );
|
||||
|
||||
void ClientThink( void );
|
||||
void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||||
|
||||
void UpdateIdle( float percentage );
|
||||
void UpdateCharging( float percentage );
|
||||
void UpdateDischarging( void );
|
||||
|
||||
private:
|
||||
|
||||
bool SetupEmitters( void );
|
||||
inline float GetStateDurationPercentage( void );
|
||||
|
||||
float m_flScale;
|
||||
int m_nState;
|
||||
float m_flDuration;
|
||||
float m_flStartTime;
|
||||
int m_spawnflags;
|
||||
|
||||
CSmartPtr<CSimpleEmitter> m_pSimpleEmitter;
|
||||
CSmartPtr<CParticleAttractor> m_pAttractorEmitter;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_CitadelEnergyCore, DT_CitadelEnergyCore, CCitadelEnergyCore )
|
||||
RecvPropFloat( RECVINFO(m_flScale) ),
|
||||
RecvPropInt( RECVINFO(m_nState) ),
|
||||
RecvPropFloat( RECVINFO(m_flDuration) ),
|
||||
RecvPropFloat( RECVINFO(m_flStartTime) ),
|
||||
RecvPropInt( RECVINFO(m_spawnflags) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : RenderGroup_t
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderGroup_t C_CitadelEnergyCore::GetRenderGroup( void )
|
||||
{
|
||||
return RENDER_GROUP_TRANSLUCENT_ENTITY;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CitadelEnergyCore::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
SetupEmitters();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_CitadelEnergyCore::SetupEmitters( void )
|
||||
{
|
||||
// Setup the basic core emitter
|
||||
if ( m_pSimpleEmitter.IsValid() == false )
|
||||
{
|
||||
m_pSimpleEmitter = CSimpleEmitter::Create( "energycore" );
|
||||
|
||||
if ( m_pSimpleEmitter.IsValid() == false )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Setup the attractor emitter
|
||||
if ( m_pAttractorEmitter.IsValid() == false )
|
||||
{
|
||||
m_pAttractorEmitter = CParticleAttractor::Create( GetAbsOrigin(), "energyattractor" );
|
||||
|
||||
if ( m_pAttractorEmitter.IsValid() == false )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : percentage -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CitadelEnergyCore::UpdateIdle( float percentage )
|
||||
{
|
||||
// Only do these particles if required
|
||||
if ( m_spawnflags & SF_ENERGYCORE_NO_PARTICLES )
|
||||
return;
|
||||
|
||||
// Must be active
|
||||
if ( percentage >= 1.0f )
|
||||
return;
|
||||
|
||||
// Emitters must be valid
|
||||
if ( SetupEmitters() == false )
|
||||
return;
|
||||
|
||||
// Reset our sort origin
|
||||
m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
// Do the charging particles
|
||||
m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
|
||||
|
||||
Vector forward, right, up;
|
||||
AngleVectors( GetAbsAngles(), &forward, &right, &up );
|
||||
|
||||
Vector offset;
|
||||
float dist;
|
||||
|
||||
int numParticles = floor( 4.0f * percentage );
|
||||
|
||||
for ( int i = 0; i < numParticles; i++ )
|
||||
{
|
||||
dist = random->RandomFloat( 4.0f * percentage, 64.0f * percentage );
|
||||
|
||||
offset = forward * dist;
|
||||
|
||||
dist = RemapValClamped( dist, 4.0f * percentage, 64.0f * percentage, 6.0f, 1.0f );
|
||||
offset += right * random->RandomFloat( -4.0f * dist, 4.0f * dist );
|
||||
offset += up * random->RandomFloat( -4.0f * dist, 4.0f * dist );
|
||||
|
||||
offset += GetAbsOrigin();
|
||||
|
||||
sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/strider_muzzle" ), offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = Vector(0,0,8);
|
||||
sParticle->m_flDieTime = 0.5f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 255 * percentage;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : percentage -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CitadelEnergyCore::UpdateCharging( float percentage )
|
||||
{
|
||||
// Emitters must be valid
|
||||
if ( SetupEmitters() == false )
|
||||
return;
|
||||
|
||||
if ( percentage <= 0.0f )
|
||||
return;
|
||||
|
||||
// Reset our sort origin
|
||||
m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
float flScale = 4.0f * m_flScale * percentage;
|
||||
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
// Do the core effects
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/strider_muzzle" ), GetAbsOrigin() );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = vec3_origin;
|
||||
sParticle->m_flDieTime = 0.1f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 255;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
if ( i < 2 )
|
||||
{
|
||||
sParticle->m_uchStartSize = flScale * (i+1);
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( random->RandomInt( 0, 20 ) == 0 )
|
||||
{
|
||||
sParticle->m_uchStartSize = flScale * (i+1);
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4.0f;
|
||||
sParticle->m_flDieTime = 0.25f;
|
||||
}
|
||||
else
|
||||
{
|
||||
sParticle->m_uchStartSize = flScale * (i+1);
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only do these particles if required
|
||||
if ( m_spawnflags & SF_ENERGYCORE_NO_PARTICLES )
|
||||
return;
|
||||
|
||||
// Do the charging particles
|
||||
m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
|
||||
|
||||
Vector forward, right, up;
|
||||
AngleVectors( GetAbsAngles(), &forward, &right, &up );
|
||||
|
||||
Vector offset;
|
||||
float dist;
|
||||
|
||||
int numParticles = floor( 4.0f * percentage );
|
||||
|
||||
for ( int i = 0; i < numParticles; i++ )
|
||||
{
|
||||
dist = random->RandomFloat( 4.0f * percentage, 64.0f * percentage );
|
||||
|
||||
offset = forward * dist;
|
||||
|
||||
dist = RemapValClamped( dist, 4.0f * percentage, 64.0f * percentage, 6.0f, 1.0f );
|
||||
offset += right * random->RandomFloat( -4.0f * dist, 4.0f * dist );
|
||||
offset += up * random->RandomFloat( -4.0f * dist, 4.0f * dist );
|
||||
|
||||
offset += GetAbsOrigin();
|
||||
|
||||
sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/strider_muzzle" ), offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = Vector(0,0,8);
|
||||
sParticle->m_flDieTime = 0.5f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 255 * percentage;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : percentage -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CitadelEnergyCore::UpdateDischarging( void )
|
||||
{
|
||||
// Emitters must be valid
|
||||
if ( SetupEmitters() == false )
|
||||
return;
|
||||
|
||||
// Reset our sort origin
|
||||
m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
float flScale = 8.0f * m_flScale;
|
||||
|
||||
Vector forward, right, up;
|
||||
AngleVectors( GetAbsAngles(), &forward, &right, &up );
|
||||
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
// Base of the core effect
|
||||
sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/strider_muzzle" ), GetAbsOrigin() );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = forward * 32.0f;
|
||||
sParticle->m_flDieTime = 0.2f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 128;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = flScale * 2.0f;
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
|
||||
|
||||
// Make sure we encompass the complete particle here!
|
||||
m_pSimpleEmitter->SetParticleCullRadius( sParticle->m_uchEndSize );
|
||||
|
||||
// Do the core effects
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( "effects/combinemuzzle2" ), GetAbsOrigin() );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = forward * ( 32.0f * (i+1) );
|
||||
sParticle->m_flDieTime = 0.2f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 100;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
if ( i < 1 )
|
||||
{
|
||||
sParticle->m_uchStartSize = flScale * (i+1);
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( random->RandomInt( 0, 20 ) == 0 )
|
||||
{
|
||||
sParticle->m_uchStartSize = flScale * (i+1);
|
||||
sParticle->m_uchEndSize = 0.0f;
|
||||
sParticle->m_flDieTime = 0.25f;
|
||||
}
|
||||
else
|
||||
{
|
||||
sParticle->m_uchStartSize = flScale * (i+1);
|
||||
sParticle->m_uchEndSize = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only do these particles if required
|
||||
if ( m_spawnflags & SF_ENERGYCORE_NO_PARTICLES )
|
||||
return;
|
||||
|
||||
// Do the charging particles
|
||||
m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
|
||||
|
||||
Vector offset;
|
||||
float dist;
|
||||
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
dist = random->RandomFloat( 4.0f * m_flScale, 64.0f * m_flScale );
|
||||
|
||||
offset = forward * dist;
|
||||
|
||||
dist = RemapValClamped( dist, 4.0f * m_flScale, 64.0f * m_flScale, 6.0f, 1.0f );
|
||||
offset += right * random->RandomFloat( -2.0f * dist * m_flScale, 2.0f * dist * m_flScale );
|
||||
offset += up * random->RandomFloat( -2.0f * dist * m_flScale, 2.0f * dist * m_flScale );
|
||||
|
||||
offset += GetAbsOrigin();
|
||||
|
||||
sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/combinemuzzle2_dark" ), offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = Vector(0,0,2);
|
||||
sParticle->m_flDieTime = 0.5f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 255;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = 1;
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : inline float
|
||||
//-----------------------------------------------------------------------------
|
||||
inline float C_CitadelEnergyCore::GetStateDurationPercentage( void )
|
||||
{
|
||||
if ( m_flDuration == 0 )
|
||||
return 0.0f;
|
||||
|
||||
return RemapValClamped( ( gpGlobals->curtime - m_flStartTime ), 0, m_flDuration, 0, 1.0f );;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CitadelEnergyCore::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||
{
|
||||
BaseClass::NotifyShouldTransmit( state );
|
||||
|
||||
// Turn off
|
||||
if ( state == SHOULDTRANSMIT_END )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
}
|
||||
|
||||
// Turn on
|
||||
if ( state == SHOULDTRANSMIT_START )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CitadelEnergyCore::ClientThink( void )
|
||||
{
|
||||
if ( gpGlobals->frametime <= 0.0f )
|
||||
return;
|
||||
|
||||
float flDuration = GetStateDurationPercentage();
|
||||
|
||||
switch( m_nState )
|
||||
{
|
||||
case ENERGYCORE_STATE_OFF:
|
||||
UpdateIdle( 1.0f - flDuration );
|
||||
break;
|
||||
|
||||
case ENERGYCORE_STATE_CHARGING:
|
||||
UpdateCharging( flDuration );
|
||||
break;
|
||||
|
||||
case ENERGYCORE_STATE_DISCHARGING:
|
||||
UpdateDischarging( );
|
||||
break;
|
||||
}
|
||||
}
|
||||
66
game/client/hl2/c_corpse.cpp
Normal file
66
game/client/hl2/c_corpse.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Implements C_Corpse
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_corpse.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_Corpse, DT_Corpse, CCorpse)
|
||||
RecvPropInt(RECVINFO(m_nReferencePlayer))
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
||||
|
||||
C_Corpse::C_Corpse()
|
||||
{
|
||||
m_nReferencePlayer = 0;
|
||||
}
|
||||
|
||||
|
||||
int C_Corpse::DrawModel( int flags )
|
||||
{
|
||||
int drawn = 0;
|
||||
if ( m_nReferencePlayer <= 0 ||
|
||||
m_nReferencePlayer > gpGlobals->maxClients )
|
||||
{
|
||||
return drawn;
|
||||
};
|
||||
|
||||
// Make sure m_pstudiohdr is valid for drawing
|
||||
if ( !GetModelPtr() )
|
||||
{
|
||||
return drawn;
|
||||
}
|
||||
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
// get copy of player
|
||||
C_BasePlayer *player = dynamic_cast< C_BasePlayer *>( cl_entitylist->GetEnt( m_nReferencePlayer ) );
|
||||
if ( player )
|
||||
{
|
||||
Vector zero;
|
||||
zero.Init();
|
||||
|
||||
drawn = modelrender->DrawModel(
|
||||
flags,
|
||||
this,
|
||||
MODEL_INSTANCE_INVALID,
|
||||
m_nReferencePlayer,
|
||||
GetModel(),
|
||||
GetAbsOrigin(),
|
||||
GetAbsAngles(),
|
||||
m_nSkin,
|
||||
m_nBody,
|
||||
m_nHitboxSet );
|
||||
}
|
||||
|
||||
return drawn;
|
||||
}
|
||||
|
||||
32
game/client/hl2/c_corpse.h
Normal file
32
game/client/hl2/c_corpse.h
Normal file
@@ -0,0 +1,32 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#if !defined( C_CORPSE_H )
|
||||
#define C_CORPSE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class C_Corpse : public C_BaseAnimating
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_Corpse, C_BaseAnimating );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_Corpse( void );
|
||||
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
public:
|
||||
// The player whom we are copying our data from
|
||||
int m_nReferencePlayer;
|
||||
|
||||
private:
|
||||
C_Corpse( const C_Corpse & );
|
||||
};
|
||||
|
||||
|
||||
#endif // C_CORPSE_H
|
||||
416
game/client/hl2/c_energy_wave.cpp
Normal file
416
game/client/hl2/c_energy_wave.cpp
Normal file
@@ -0,0 +1,416 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client's energy wave
|
||||
//
|
||||
// $Workfile: $
|
||||
// $Date: $
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// $Log: $
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "energy_wave_effect.h"
|
||||
#include "mathlib/vmatrix.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEnergyWave )
|
||||
CLIENTEFFECT_MATERIAL( "effects/energywave/energywave" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Energy Wave:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class C_EnergyWave : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_EnergyWave, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_EnergyWave();
|
||||
~C_EnergyWave();
|
||||
|
||||
void PostDataUpdate( DataUpdateType_t updateType );
|
||||
int DrawModel( int flags );
|
||||
void ComputePoint( float s, float t, Vector& pt, Vector& normal, float& opacity );
|
||||
void DrawWireframeModel( );
|
||||
|
||||
CEnergyWaveEffect m_EWaveEffect;
|
||||
|
||||
IMaterial* m_pWireframe;
|
||||
IMaterial* m_pEWaveMat;
|
||||
|
||||
private:
|
||||
C_EnergyWave( const C_EnergyWave & ); // not defined, not accessible
|
||||
|
||||
void ComputeEWavePoints( Vector* pt, Vector* normal, float* opacity );
|
||||
void DrawEWavePoints(Vector* pt, Vector* normal, float* opacity);
|
||||
|
||||
};
|
||||
|
||||
|
||||
EXTERN_RECV_TABLE(DT_BaseEntity);
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_EnergyWave, DT_EWaveEffect, CEnergyWave)
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Functions.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
C_EnergyWave::C_EnergyWave() : m_EWaveEffect(NULL, NULL)
|
||||
{
|
||||
m_pWireframe = materials->FindMaterial("shadertest/wireframevertexcolor", TEXTURE_GROUP_OTHER);
|
||||
m_pEWaveMat = materials->FindMaterial("effects/energywave/energywave", TEXTURE_GROUP_CLIENT_EFFECTS);
|
||||
m_EWaveEffect.Spawn();
|
||||
}
|
||||
|
||||
C_EnergyWave::~C_EnergyWave()
|
||||
{
|
||||
}
|
||||
|
||||
void C_EnergyWave::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
MarkMessageReceived();
|
||||
|
||||
// Make sure that origin points to current origin, at least
|
||||
MoveToLastReceivedPosition();
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_SUBDIVISIONS = 21,
|
||||
};
|
||||
|
||||
|
||||
static void ComputeIndices( int is, int it, int* idx )
|
||||
{
|
||||
int is0 = (is > 0) ? (is - 1) : is;
|
||||
int it0 = (it > 0) ? (it - 1) : it;
|
||||
int is1 = (is < EWAVE_NUM_HORIZONTAL_POINTS - 1) ? is + 1 : is;
|
||||
int it1 = (it < EWAVE_NUM_HORIZONTAL_POINTS - 1) ? it + 1 : it;
|
||||
int is2 = is + 2;
|
||||
int it2 = it + 2;
|
||||
if (is2 >= EWAVE_NUM_HORIZONTAL_POINTS)
|
||||
is2 = EWAVE_NUM_HORIZONTAL_POINTS - 1;
|
||||
if (it2 >= EWAVE_NUM_HORIZONTAL_POINTS)
|
||||
it2 = EWAVE_NUM_HORIZONTAL_POINTS - 1;
|
||||
|
||||
idx[0] = is0 + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[1] = is + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[2] = is1 + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[3] = is2 + it0 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
|
||||
idx[4] = is0 + it * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[5] = is + it * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[6] = is1 + it * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[7] = is2 + it * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
|
||||
idx[8] = is0 + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[9] = is + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[10] = is1 + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[11] = is2 + it1 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
|
||||
idx[12] = is0 + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[13] = is + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[14] = is1 + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
idx[15] = is2 + it2 * EWAVE_NUM_HORIZONTAL_POINTS;
|
||||
}
|
||||
|
||||
void C_EnergyWave::ComputePoint( float s, float t, Vector& pt, Vector& normal, float& opacity )
|
||||
{
|
||||
int is = (int)s;
|
||||
int it = (int)t;
|
||||
if( is >= EWAVE_NUM_HORIZONTAL_POINTS )
|
||||
is -= 1;
|
||||
|
||||
if( it >= EWAVE_NUM_VERTICAL_POINTS )
|
||||
it -= 1;
|
||||
|
||||
int idx[16];
|
||||
ComputeIndices( is, it, idx );
|
||||
|
||||
// The patch equation is:
|
||||
// px = S * M * Gx * M^T * T^T
|
||||
// py = S * M * Gy * M^T * T^T
|
||||
// pz = S * M * Gz * M^T * T^T
|
||||
// where S = [s^3 s^2 s 1], T = [t^3 t^2 t 1]
|
||||
// M is the patch type matrix, in my case I'm using a catmull-rom
|
||||
// G is the array of control points. rows have constant t
|
||||
static VMatrix catmullRom( -0.5, 1.5, -1.5, 0.5,
|
||||
1, -2.5, 2, -0.5,
|
||||
-0.5, 0, 0.5, 0,
|
||||
0, 1, 0, 0 );
|
||||
|
||||
VMatrix controlPointsX, controlPointsY, controlPointsZ, controlPointsO;
|
||||
|
||||
Vector pos;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
const Vector& v = m_EWaveEffect.GetPoint( idx[i * 4 + j] );
|
||||
|
||||
controlPointsX[j][i] = v.x;
|
||||
controlPointsY[j][i] = v.y;
|
||||
controlPointsZ[j][i] = v.z;
|
||||
|
||||
controlPointsO[j][i] = m_EWaveEffect.ComputeOpacity( v, GetAbsOrigin() );
|
||||
}
|
||||
}
|
||||
|
||||
float fs = s - is;
|
||||
float ft = t - it;
|
||||
|
||||
VMatrix temp, mgm[4];
|
||||
MatrixTranspose( catmullRom, temp );
|
||||
MatrixMultiply( controlPointsX, temp, mgm[0] );
|
||||
MatrixMultiply( controlPointsY, temp, mgm[1] );
|
||||
MatrixMultiply( controlPointsZ, temp, mgm[2] );
|
||||
MatrixMultiply( controlPointsO, temp, mgm[3] );
|
||||
|
||||
MatrixMultiply( catmullRom, mgm[0], mgm[0] );
|
||||
MatrixMultiply( catmullRom, mgm[1], mgm[1] );
|
||||
MatrixMultiply( catmullRom, mgm[2], mgm[2] );
|
||||
MatrixMultiply( catmullRom, mgm[3], mgm[3] );
|
||||
|
||||
Vector4D svec, tvec;
|
||||
float ft2 = ft * ft;
|
||||
tvec[0] = ft2 * ft; tvec[1] = ft2; tvec[2] = ft; tvec[3] = 1.0f;
|
||||
|
||||
float fs2 = fs * fs;
|
||||
svec[0] = fs2 * fs; svec[1] = fs2; svec[2] = fs; svec[3] = 1.0f;
|
||||
|
||||
Vector4D tmp;
|
||||
Vector4DMultiply( mgm[0], tvec, tmp );
|
||||
pt[0] = DotProduct4D( tmp, svec );
|
||||
Vector4DMultiply( mgm[1], tvec, tmp );
|
||||
pt[1] = DotProduct4D( tmp, svec );
|
||||
Vector4DMultiply( mgm[2], tvec, tmp );
|
||||
pt[2] = DotProduct4D( tmp, svec );
|
||||
|
||||
Vector4DMultiply( mgm[3], tvec, tmp );
|
||||
opacity = DotProduct4D( tmp, svec );
|
||||
|
||||
if ((s == 0.0f) || (t == 0.0f) ||
|
||||
(s == (EWAVE_NUM_HORIZONTAL_POINTS-1.0f)) || (t == (EWAVE_NUM_VERTICAL_POINTS-1.0f)) )
|
||||
{
|
||||
opacity = 0.0f;
|
||||
}
|
||||
|
||||
if ((s <= 0.3) || (t < 0.3))
|
||||
{
|
||||
opacity *= 0.35f;
|
||||
}
|
||||
if ((s == (EWAVE_NUM_HORIZONTAL_POINTS-0.7f)) || (t == (EWAVE_NUM_VERTICAL_POINTS-0.7f)) )
|
||||
{
|
||||
opacity *= 0.35f;
|
||||
}
|
||||
|
||||
if (opacity < 0.0f)
|
||||
opacity = 0.0f;
|
||||
else if (opacity > 255.0f)
|
||||
opacity = 255.0f;
|
||||
|
||||
// Normal computation
|
||||
Vector4D dsvec, dtvec;
|
||||
dsvec[0] = 3.0f * fs2; dsvec[1] = 2.0f * fs; dsvec[2] = 1.0f; dsvec[3] = 0.0f;
|
||||
dtvec[0] = 3.0f * ft2; dtvec[1] = 2.0f * ft; dtvec[2] = 1.0f; dtvec[3] = 0.0f;
|
||||
|
||||
Vector ds, dt;
|
||||
Vector4DMultiply( mgm[0], tvec, tmp );
|
||||
ds[0] = DotProduct4D( tmp, dsvec );
|
||||
Vector4DMultiply( mgm[1], tvec, tmp );
|
||||
ds[1] = DotProduct4D( tmp, dsvec );
|
||||
Vector4DMultiply( mgm[2], tvec, tmp );
|
||||
ds[2] = DotProduct4D( tmp, dsvec );
|
||||
|
||||
Vector4DMultiply( mgm[0], dtvec, tmp );
|
||||
dt[0] = DotProduct4D( tmp, svec );
|
||||
Vector4DMultiply( mgm[1], dtvec, tmp );
|
||||
dt[1] = DotProduct4D( tmp, svec );
|
||||
Vector4DMultiply( mgm[2], dtvec, tmp );
|
||||
dt[2] = DotProduct4D( tmp, svec );
|
||||
|
||||
CrossProduct( ds, dt, normal );
|
||||
VectorNormalize( normal );
|
||||
}
|
||||
|
||||
void C_EnergyWave::DrawWireframeModel( )
|
||||
{
|
||||
IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL, m_pWireframe );
|
||||
|
||||
int numLines = (EWAVE_NUM_VERTICAL_POINTS - 1) * EWAVE_NUM_HORIZONTAL_POINTS +
|
||||
EWAVE_NUM_VERTICAL_POINTS * (EWAVE_NUM_HORIZONTAL_POINTS - 1);
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_LINES, numLines );
|
||||
|
||||
Vector tmp;
|
||||
for (int i = 0; i < EWAVE_NUM_VERTICAL_POINTS; ++i)
|
||||
{
|
||||
for (int j = 0; j < EWAVE_NUM_HORIZONTAL_POINTS; ++j)
|
||||
{
|
||||
if ( i > 0 )
|
||||
{
|
||||
meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j, i ).Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 128 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j, i - 1 ).Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 128 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
|
||||
if (j > 0)
|
||||
{
|
||||
meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j, i ).Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 128 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( m_EWaveEffect.GetPoint( j - 1, i ).Base() );
|
||||
meshBuilder.Color4ub( 255, 255, 255, 128 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute the ewave points using catmull-rom
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_EnergyWave::ComputeEWavePoints( Vector* pt, Vector* normal, float* opacity )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < NUM_SUBDIVISIONS; ++i)
|
||||
{
|
||||
float t = (EWAVE_NUM_VERTICAL_POINTS -1 ) * (float)i / (float)(NUM_SUBDIVISIONS - 1);
|
||||
for (int j = 0; j < NUM_SUBDIVISIONS; ++j)
|
||||
{
|
||||
float s = (EWAVE_NUM_HORIZONTAL_POINTS-1) * (float)j / (float)(NUM_SUBDIVISIONS - 1);
|
||||
int idx = i * NUM_SUBDIVISIONS + j;
|
||||
|
||||
ComputePoint( s, t, pt[idx], normal[idx], opacity[idx] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draws the base ewave
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define TRANSITION_REGION_WIDTH 0.5f
|
||||
|
||||
void C_EnergyWave::DrawEWavePoints(Vector* pt, Vector* normal, float* opacity)
|
||||
{
|
||||
IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL, m_pEWaveMat );
|
||||
|
||||
int numTriangles = (NUM_SUBDIVISIONS - 1) * (NUM_SUBDIVISIONS - 1) * 2;
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, numTriangles );
|
||||
|
||||
float du = 1.0f / (float)(NUM_SUBDIVISIONS - 1);
|
||||
float dv = du;
|
||||
|
||||
unsigned char color[3];
|
||||
color[0] = 255;
|
||||
color[1] = 255;
|
||||
color[2] = 255;
|
||||
|
||||
for ( int i = 0; i < NUM_SUBDIVISIONS - 1; ++i)
|
||||
{
|
||||
float v = i * dv;
|
||||
for (int j = 0; j < NUM_SUBDIVISIONS - 1; ++j)
|
||||
{
|
||||
int idx = i * NUM_SUBDIVISIONS + j;
|
||||
float u = j * du;
|
||||
|
||||
meshBuilder.Position3fv( pt[idx].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx] );
|
||||
meshBuilder.Normal3fv( normal[idx].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u, v );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + NUM_SUBDIVISIONS].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+NUM_SUBDIVISIONS] );
|
||||
meshBuilder.Normal3fv( normal[idx + NUM_SUBDIVISIONS].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u, v + dv );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + 1].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+1] );
|
||||
meshBuilder.Normal3fv( normal[idx+1].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u + du, v );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + 1].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+1] );
|
||||
meshBuilder.Normal3fv( normal[idx+1].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u + du, v );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + NUM_SUBDIVISIONS].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+NUM_SUBDIVISIONS] );
|
||||
meshBuilder.Normal3fv( normal[idx + NUM_SUBDIVISIONS].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u, v + dv );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Position3fv( pt[idx + NUM_SUBDIVISIONS + 1].Base() );
|
||||
meshBuilder.Color4ub( color[0], color[1], color[2], opacity[idx+NUM_SUBDIVISIONS+1] );
|
||||
meshBuilder.Normal3fv( normal[idx + NUM_SUBDIVISIONS + 1].Base() );
|
||||
meshBuilder.TexCoord2f( 0, u + du, v + dv );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main draw entry point
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int C_EnergyWave::DrawModel( int flags )
|
||||
{
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
// NOTE: We've got a stiff spring case here, we need to simulate at
|
||||
// a fairly fast timestep. A better solution would be to use an
|
||||
// implicit method, which I'm going to not implement for the moment
|
||||
|
||||
float dt = gpGlobals->frametime;
|
||||
m_EWaveEffect.SetPosition( GetAbsOrigin(), GetAbsAngles() );
|
||||
m_EWaveEffect.Simulate(dt);
|
||||
|
||||
Vector pt[NUM_SUBDIVISIONS * NUM_SUBDIVISIONS];
|
||||
Vector normal[NUM_SUBDIVISIONS * NUM_SUBDIVISIONS];
|
||||
float opacity[NUM_SUBDIVISIONS * NUM_SUBDIVISIONS];
|
||||
|
||||
ComputeEWavePoints( pt, normal, opacity );
|
||||
|
||||
DrawEWavePoints( pt, normal, opacity );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
486
game/client/hl2/c_env_alyxtemp.cpp
Normal file
486
game/client/hl2/c_env_alyxtemp.cpp
Normal file
@@ -0,0 +1,486 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "particles_simple.h"
|
||||
#include "citadel_effects_shared.h"
|
||||
#include "particles_attractor.h"
|
||||
|
||||
class C_AlyxEmpEffect : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_AlyxEmpEffect, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
public:
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
RenderGroup_t GetRenderGroup( void );
|
||||
|
||||
void ClientThink( void );
|
||||
void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||||
|
||||
void UpdateIdle( float percentage );
|
||||
void UpdateCharging( float percentage );
|
||||
void UpdateDischarging( void );
|
||||
|
||||
private:
|
||||
|
||||
bool SetupEmitters( void );
|
||||
inline float GetStateDurationPercentage( void );
|
||||
|
||||
int m_nState;
|
||||
float m_flDuration;
|
||||
float m_flStartTime;
|
||||
TimedEvent m_tParticleSpawn;
|
||||
|
||||
CSmartPtr<CSimpleEmitter> m_pSimpleEmitter;
|
||||
CSmartPtr<CParticleAttractor> m_pAttractorEmitter;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_AlyxEmpEffect, DT_AlyxEmpEffect, CAlyxEmpEffect )
|
||||
RecvPropInt( RECVINFO(m_nState) ),
|
||||
RecvPropFloat( RECVINFO(m_flDuration) ),
|
||||
RecvPropFloat( RECVINFO(m_flStartTime) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : RenderGroup_t
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderGroup_t C_AlyxEmpEffect::GetRenderGroup( void )
|
||||
{
|
||||
return RENDER_GROUP_TRANSLUCENT_ENTITY;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_AlyxEmpEffect::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_tParticleSpawn.Init( 32 );
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
SetupEmitters();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_AlyxEmpEffect::SetupEmitters( void )
|
||||
{
|
||||
// Setup the basic core emitter
|
||||
if ( m_pSimpleEmitter.IsValid() == false )
|
||||
{
|
||||
m_pSimpleEmitter = CSimpleEmitter::Create( "energycore" );
|
||||
|
||||
if ( m_pSimpleEmitter.IsValid() == false )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Setup the attractor emitter
|
||||
if ( m_pAttractorEmitter.IsValid() == false )
|
||||
{
|
||||
m_pAttractorEmitter = CParticleAttractor::Create( GetAbsOrigin(), "energyattractor" );
|
||||
|
||||
if ( m_pAttractorEmitter.IsValid() == false )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define EMP_SCALE 0.5f
|
||||
|
||||
#define EMP_PARTICLES "effects/ar2_altfire1b"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : percentage -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_AlyxEmpEffect::UpdateIdle( float percentage )
|
||||
{
|
||||
#if 0
|
||||
|
||||
// Must be active
|
||||
if ( percentage >= 1.0f )
|
||||
return;
|
||||
|
||||
// Emitters must be valid
|
||||
if ( SetupEmitters() == false )
|
||||
return;
|
||||
|
||||
// Reset our sort origin
|
||||
m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
// Do the charging particles
|
||||
m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
|
||||
|
||||
Vector forward, right, up;
|
||||
AngleVectors( GetAbsAngles(), &forward, &right, &up );
|
||||
|
||||
Vector offset;
|
||||
float dist;
|
||||
|
||||
int numParticles = floor( 4.0f * percentage );
|
||||
|
||||
float dTime = gpGlobals->frametime;
|
||||
|
||||
while ( m_tParticleSpawn.NextEvent( dTime ) )
|
||||
{
|
||||
for ( int i = 0; i < numParticles; i++ )
|
||||
{
|
||||
dist = random->RandomFloat( 4.0f * EMP_SCALE * percentage, 64.0f * EMP_SCALE * percentage );
|
||||
|
||||
offset = forward * dist;
|
||||
|
||||
dist = RemapValClamped( dist, 4.0f * EMP_SCALE * percentage, 64.0f * EMP_SCALE * percentage, 6.0f, 1.0f );
|
||||
offset += right * random->RandomFloat( -4.0f * EMP_SCALE * dist, 4.0f * EMP_SCALE * dist );
|
||||
offset += up * random->RandomFloat( -4.0f * EMP_SCALE * dist, 4.0f * EMP_SCALE * dist );
|
||||
|
||||
offset += GetAbsOrigin();
|
||||
|
||||
sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( EMP_PARTICLES ), offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = Vector(0,0,8);
|
||||
sParticle->m_flDieTime = 0.5f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 255 * percentage;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : percentage -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_AlyxEmpEffect::UpdateCharging( float percentage )
|
||||
{
|
||||
// Emitters must be valid
|
||||
if ( SetupEmitters() == false )
|
||||
return;
|
||||
|
||||
if ( percentage <= 0.0f )
|
||||
return;
|
||||
|
||||
// Reset our sort origin
|
||||
m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
float flScale = 4.0f * EMP_SCALE * percentage;
|
||||
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
float dTime = gpGlobals->frametime;
|
||||
|
||||
while ( m_tParticleSpawn.NextEvent( dTime ) )
|
||||
{
|
||||
// Do the core effects
|
||||
sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = vec3_origin;
|
||||
sParticle->m_flDieTime = 0.1f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 255 * percentage;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = flScale;
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// Do the charging particles
|
||||
m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
|
||||
|
||||
Vector forward, right, up;
|
||||
AngleVectors( GetAbsAngles(), &forward, &right, &up );
|
||||
|
||||
Vector offset;
|
||||
float dist;
|
||||
|
||||
int numParticles = floor( 4.0f * percentage );
|
||||
|
||||
for ( i = 0; i < numParticles; i++ )
|
||||
{
|
||||
dist = random->RandomFloat( 4.0f * percentage, 64.0f * percentage );
|
||||
|
||||
offset = forward * dist;
|
||||
|
||||
dist = RemapValClamped( dist, 4.0f * percentage, 64.0f * percentage, 6.0f, 1.0f );
|
||||
offset += right * random->RandomFloat( -4.0f * dist, 4.0f * dist );
|
||||
offset += up * random->RandomFloat( -4.0f * dist, 4.0f * dist );
|
||||
|
||||
offset += GetAbsOrigin();
|
||||
|
||||
sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( EMP_PARTICLES ), offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = Vector(0,0,8);
|
||||
sParticle->m_flDieTime = 0.5f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 255 * percentage;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : percentage -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_AlyxEmpEffect::UpdateDischarging( void )
|
||||
{
|
||||
// Emitters must be valid
|
||||
if ( SetupEmitters() == false )
|
||||
return;
|
||||
|
||||
// Reset our sort origin
|
||||
m_pSimpleEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
float flScale = EMP_SCALE * 8.0f;
|
||||
|
||||
Vector forward, right, up;
|
||||
AngleVectors( GetAbsAngles(), &forward, &right, &up );
|
||||
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
float dTime = gpGlobals->frametime;
|
||||
|
||||
while ( m_tParticleSpawn.NextEvent( dTime ) )
|
||||
{
|
||||
// Base of the core effect
|
||||
sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = vec3_origin;
|
||||
sParticle->m_flDieTime = 0.25f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 64;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = flScale * 4.0f;
|
||||
sParticle->m_uchEndSize = 0.0f;
|
||||
|
||||
// Base of the core effect
|
||||
sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = vec3_origin;
|
||||
sParticle->m_flDieTime = 0.1f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
alpha = 128;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = 0.0f;
|
||||
sParticle->m_uchEndSize = flScale * 2.0f;
|
||||
|
||||
// Make sure we encompass the complete particle here!
|
||||
m_pSimpleEmitter->SetParticleCullRadius( sParticle->m_uchEndSize );
|
||||
|
||||
// Do the core effects
|
||||
sParticle = (SimpleParticle *) m_pSimpleEmitter->AddParticle( sizeof(SimpleParticle), m_pSimpleEmitter->GetPMaterial( EMP_PARTICLES ), GetAbsOrigin() );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = RandomVector( -32.0f, 32.0f );
|
||||
sParticle->m_flDieTime = 0.2f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
alpha = 255;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = flScale;
|
||||
sParticle->m_uchEndSize = 0.0f;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// Do the charging particles
|
||||
m_pAttractorEmitter->SetAttractorOrigin( GetAbsOrigin() );
|
||||
|
||||
Vector offset;
|
||||
float dist;
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
dist = random->RandomFloat( 4.0f, 64.0f );
|
||||
|
||||
offset = forward * dist;
|
||||
|
||||
dist = RemapValClamped( dist, 4.0f, 64.0f, 6.0f, 1.0f );
|
||||
offset += right * random->RandomFloat( -2.0f * dist, 2.0f * dist );
|
||||
offset += up * random->RandomFloat( -2.0f * dist, 2.0f * dist );
|
||||
|
||||
offset += GetAbsOrigin();
|
||||
|
||||
sParticle = (SimpleParticle *) m_pAttractorEmitter->AddParticle( sizeof(SimpleParticle), m_pAttractorEmitter->GetPMaterial( "effects/combinemuzzle2_dark" ), offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = Vector(0,0,2);
|
||||
sParticle->m_flDieTime = 0.5f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 255;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = 1;
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : inline float
|
||||
//-----------------------------------------------------------------------------
|
||||
inline float C_AlyxEmpEffect::GetStateDurationPercentage( void )
|
||||
{
|
||||
if ( m_flDuration == 0 )
|
||||
return 0.0f;
|
||||
|
||||
return RemapValClamped( ( gpGlobals->curtime - m_flStartTime ), 0, m_flDuration, 0, 1.0f );;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_AlyxEmpEffect::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||
{
|
||||
BaseClass::NotifyShouldTransmit( state );
|
||||
|
||||
// Turn off
|
||||
if ( state == SHOULDTRANSMIT_END )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
}
|
||||
|
||||
// Turn on
|
||||
if ( state == SHOULDTRANSMIT_START )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_AlyxEmpEffect::ClientThink( void )
|
||||
{
|
||||
if ( gpGlobals->frametime <= 0.0f )
|
||||
return;
|
||||
|
||||
float flDuration = GetStateDurationPercentage();
|
||||
|
||||
switch( m_nState )
|
||||
{
|
||||
case ENERGYCORE_STATE_OFF:
|
||||
UpdateIdle( 1.0f - flDuration );
|
||||
break;
|
||||
|
||||
case ENERGYCORE_STATE_CHARGING:
|
||||
UpdateCharging( flDuration );
|
||||
break;
|
||||
|
||||
case ENERGYCORE_STATE_DISCHARGING:
|
||||
UpdateDischarging( );
|
||||
break;
|
||||
}
|
||||
}
|
||||
97
game/client/hl2/c_env_headcrabcanister.cpp
Normal file
97
game/client/hl2/c_env_headcrabcanister.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "fx_explosion.h"
|
||||
#include "tempentity.h"
|
||||
#include "c_tracer.h"
|
||||
#include "env_headcrabcanister_shared.h"
|
||||
#include "baseparticleentity.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Headcrab canister Class (Client-side only!)
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EnvHeadcrabCanister : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_EnvHeadcrabCanister, C_BaseAnimating );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
public:
|
||||
//-------------------------------------------------------------------------
|
||||
// Initialization/Destruction
|
||||
//-------------------------------------------------------------------------
|
||||
C_EnvHeadcrabCanister();
|
||||
~C_EnvHeadcrabCanister();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink();
|
||||
|
||||
private:
|
||||
C_EnvHeadcrabCanister( const C_EnvHeadcrabCanister & );
|
||||
|
||||
CEnvHeadcrabCanisterShared m_Shared;
|
||||
CNetworkVar( bool, m_bLanded );
|
||||
};
|
||||
|
||||
|
||||
EXTERN_RECV_TABLE(DT_EnvHeadcrabCanisterShared);
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvHeadcrabCanister, DT_EnvHeadcrabCanister, CEnvHeadcrabCanister )
|
||||
RecvPropDataTable( RECVINFO_DT( m_Shared ), 0, &REFERENCE_RECV_TABLE(DT_EnvHeadcrabCanisterShared) ),
|
||||
RecvPropBool( RECVINFO( m_bLanded ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvHeadcrabCanister::C_EnvHeadcrabCanister()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_EnvHeadcrabCanister::~C_EnvHeadcrabCanister()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// On data update
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvHeadcrabCanister::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
// Stop client-side simulation on landing
|
||||
if ( m_bLanded )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_NEVER );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute position
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvHeadcrabCanister::ClientThink()
|
||||
{
|
||||
Vector vecEndPosition;
|
||||
QAngle vecEndAngles;
|
||||
m_Shared.GetPositionAtTime( gpGlobals->curtime, vecEndPosition, vecEndAngles );
|
||||
SetAbsOrigin( vecEndPosition );
|
||||
SetAbsAngles( vecEndAngles );
|
||||
}
|
||||
|
||||
132
game/client/hl2/c_env_starfield.cpp
Normal file
132
game/client/hl2/c_env_starfield.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "engine/IEngineTrace.h"
|
||||
#include "fx_sparks.h"
|
||||
#include "particles_ez.h"
|
||||
#include "view.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
ConVar cl_starfield_diameter( "cl_starfield_diameter", "128.0", FCVAR_NONE );
|
||||
ConVar cl_starfield_distance( "cl_starfield_distance", "256.0", FCVAR_NONE );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_EnvStarfield : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_EnvStarfield, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_EnvStarfield();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
private:
|
||||
// Emitter
|
||||
CSmartPtr<CTrailParticles> m_pEmitter;
|
||||
bool m_bOn;
|
||||
float m_flDensity;
|
||||
float m_flNumParticles;
|
||||
|
||||
private:
|
||||
C_EnvStarfield( const C_EnvStarfield & );
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_EnvStarfield, DT_EnvStarfield, CEnvStarfield )
|
||||
RecvPropInt( RECVINFO(m_bOn) ),
|
||||
RecvPropFloat( RECVINFO(m_flDensity) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
// C_EnvStarfield
|
||||
// ------------------------------------------------------------------------- //
|
||||
C_EnvStarfield::C_EnvStarfield()
|
||||
{
|
||||
m_bOn = false;
|
||||
m_flDensity = 1.0;
|
||||
m_flNumParticles = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvStarfield::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_pEmitter = CTrailParticles::Create( "EnvStarfield" );
|
||||
Vector vecCenter = MainViewOrigin() + (MainViewForward() * cl_starfield_distance.GetFloat() );
|
||||
m_pEmitter->Setup( (Vector &) vecCenter,
|
||||
NULL,
|
||||
0.0,
|
||||
0,
|
||||
64,
|
||||
0,
|
||||
0,
|
||||
bitsPARTICLE_TRAIL_VELOCITY_DAMPEN | bitsPARTICLE_TRAIL_FADE | bitsPARTICLE_TRAIL_FADE_IN );
|
||||
|
||||
// Start thinking
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_EnvStarfield::ClientThink( void )
|
||||
{
|
||||
if ( !m_bOn || !m_flDensity )
|
||||
return;
|
||||
|
||||
PMaterialHandle hParticleMaterial = m_pEmitter->GetPMaterial( "effects/spark_noz" );
|
||||
|
||||
// Find a start & end point for the particle
|
||||
// Start particles straight ahead of the client
|
||||
Vector vecViewOrigin = MainViewOrigin();
|
||||
|
||||
// Determine the number of particles
|
||||
m_flNumParticles += 1.0 * (m_flDensity);
|
||||
int iNumParticles = floor(m_flNumParticles);
|
||||
m_flNumParticles -= iNumParticles;
|
||||
|
||||
// Add particles
|
||||
for ( int i = 0; i < iNumParticles; i++ )
|
||||
{
|
||||
float flDiameter = cl_starfield_diameter.GetFloat();
|
||||
|
||||
Vector vecStart = vecViewOrigin + (MainViewForward() * cl_starfield_distance.GetFloat() );
|
||||
Vector vecEnd = vecViewOrigin + (MainViewRight() * RandomFloat(-flDiameter,flDiameter)) + (MainViewUp() * RandomFloat(-flDiameter,flDiameter));
|
||||
Vector vecDir = (vecEnd - vecStart);
|
||||
float flDistance = VectorNormalize( vecDir );
|
||||
float flTravelTime = 2.0;
|
||||
|
||||
// Start a random amount along the path
|
||||
vecStart += vecDir * ( RandomFloat(0.1,0.3) * flDistance );
|
||||
|
||||
TrailParticle *pParticle = (TrailParticle *) m_pEmitter->AddParticle( sizeof(TrailParticle), hParticleMaterial, vecStart );
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_vecVelocity = vecDir * (flDistance / flTravelTime);
|
||||
pParticle->m_flDieTime = flTravelTime;
|
||||
pParticle->m_flLifetime = 0;
|
||||
pParticle->m_flWidth = RandomFloat( 1, 3 );
|
||||
pParticle->m_flLength = RandomFloat( 0.05, 0.4 );
|
||||
pParticle->m_color.r = 255;
|
||||
pParticle->m_color.g = 255;
|
||||
pParticle->m_color.b = 255;
|
||||
pParticle->m_color.a = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
413
game/client/hl2/c_extinguisher.cpp
Normal file
413
game/client/hl2/c_extinguisher.cpp
Normal file
@@ -0,0 +1,413 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "particles_simple.h"
|
||||
#include "baseparticleentity.h"
|
||||
#include "iefx.h"
|
||||
#include "decals.h"
|
||||
#include "beamdraw.h"
|
||||
#include "hud.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheExtinguisher )
|
||||
CLIENTEFFECT_MATERIAL( "particle/particle_smokegrenade" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
class C_ExtinguisherJet : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_ExtinguisherJet, C_BaseEntity );
|
||||
|
||||
C_ExtinguisherJet();
|
||||
~C_ExtinguisherJet();
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
void Update( float fTimeDelta );
|
||||
void Start( void );
|
||||
int DrawModel( int flags );
|
||||
bool ShouldDraw( void ) { return m_bEmit; }
|
||||
|
||||
protected:
|
||||
|
||||
void AddExtinguisherDecal( trace_t &tr );
|
||||
|
||||
bool m_bEmit;
|
||||
bool m_bUseMuzzlePoint;
|
||||
int m_nLength;
|
||||
int m_nSize;
|
||||
|
||||
PMaterialHandle m_MaterialHandle;
|
||||
PMaterialHandle m_EmberMaterialHandle;
|
||||
TimedEvent m_ParticleSpawn;
|
||||
CSmartPtr<CSimpleEmitter> m_pEmitter;
|
||||
CSmartPtr<CEmberEffect> m_pEmberEmitter;
|
||||
|
||||
private:
|
||||
C_ExtinguisherJet( const C_ExtinguisherJet & );
|
||||
};
|
||||
|
||||
//Datatable
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ExtinguisherJet, DT_ExtinguisherJet, CExtinguisherJet )
|
||||
RecvPropInt(RECVINFO(m_bEmit), 0),
|
||||
RecvPropInt(RECVINFO(m_bUseMuzzlePoint), 0),
|
||||
RecvPropInt(RECVINFO(m_nLength), 0),
|
||||
RecvPropInt(RECVINFO(m_nSize), 0),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ExtinguisherJet::C_ExtinguisherJet( void )
|
||||
{
|
||||
m_bEmit = false;
|
||||
|
||||
m_pEmitter = NULL;
|
||||
m_pEmberEmitter = NULL;
|
||||
}
|
||||
|
||||
C_ExtinguisherJet::~C_ExtinguisherJet( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bnewentity -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ExtinguisherJet::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
C_BaseEntity::OnDataChanged(updateType);
|
||||
|
||||
if( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ExtinguisherJet::Start( void )
|
||||
{
|
||||
AddToLeafSystem( RENDER_GROUP_TRANSLUCENT_ENTITY );
|
||||
|
||||
m_ParticleSpawn.Init( 100 ); //Events per second
|
||||
|
||||
//Create the basic emitter
|
||||
m_pEmitter = CSimpleEmitter::Create("C_ExtinguisherJet::m_pEmitter");
|
||||
|
||||
Assert( m_pEmitter.IsValid() );
|
||||
if ( m_pEmitter.IsValid() )
|
||||
{
|
||||
m_MaterialHandle = g_Mat_DustPuff[0];
|
||||
m_pEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
}
|
||||
|
||||
//Create the "ember" emitter for the smaller flecks
|
||||
m_pEmberEmitter = CEmberEffect::Create( "C_ExtinguisherJet::m_pEmberEmitter" );
|
||||
|
||||
Assert( m_pEmberEmitter.IsValid() );
|
||||
if ( m_pEmberEmitter.IsValid() )
|
||||
{
|
||||
m_EmberMaterialHandle = g_Mat_DustPuff[0];
|
||||
m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ExtinguisherJet::AddExtinguisherDecal( trace_t &tr )
|
||||
{
|
||||
C_BaseEntity *ent = cl_entitylist->GetEnt( 0 );
|
||||
|
||||
if ( ent != NULL )
|
||||
{
|
||||
int index = decalsystem->GetDecalIndexForName( "Extinguish" );
|
||||
if ( index >= 0 )
|
||||
{
|
||||
Vector endpos;
|
||||
endpos.Random( -24.0f, 24.0f );
|
||||
endpos += tr.endpos;
|
||||
|
||||
effects->DecalShoot( index, 0, ent->GetModel(), ent->GetAbsOrigin(), ent->GetAbsAngles(), endpos, 0, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : fTimeDelta -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ExtinguisherJet::Update( float fTimeDelta )
|
||||
{
|
||||
if ( m_bEmit == false )
|
||||
return;
|
||||
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
|
||||
if ( m_bUseMuzzlePoint )
|
||||
{
|
||||
C_BaseViewModel *vm = player ? player->GetViewModel( 0 ) : NULL;
|
||||
|
||||
if ( vm )
|
||||
{
|
||||
int iAttachment = vm->LookupAttachment( "muzzle" );
|
||||
Vector origin;
|
||||
QAngle angles;
|
||||
vm->GetAttachment( iAttachment, origin, angles );
|
||||
|
||||
Assert( !GetMoveParent() );
|
||||
SetLocalOrigin( origin );
|
||||
SetLocalAngles( angles );
|
||||
}
|
||||
}
|
||||
|
||||
trace_t tr;
|
||||
Vector shotDir, vRight, vUp;
|
||||
|
||||
AngleVectors( GetAbsAngles(), &shotDir, &vRight, &vUp );
|
||||
|
||||
//FIXME: Muzzle point is incorrect on the model!
|
||||
if ( m_bUseMuzzlePoint )
|
||||
{
|
||||
shotDir.Negate();
|
||||
}
|
||||
|
||||
Vector endPoint = GetAbsOrigin() + ( shotDir * 150.0f );
|
||||
|
||||
UTIL_TraceLine( GetAbsOrigin(), endPoint, MASK_SHOT, NULL, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
bool hitWall = ( tr.fraction < 1.0f );
|
||||
|
||||
//Add normal jet
|
||||
if ( m_pEmitter.IsValid() )
|
||||
{
|
||||
SimpleParticle *pParticle;
|
||||
|
||||
m_pEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
float tempDelta = fTimeDelta;
|
||||
|
||||
//FIXME: All particles need to be within this loop
|
||||
while( m_ParticleSpawn.NextEvent( tempDelta ) )
|
||||
{
|
||||
pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() );
|
||||
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_flDieTime = 0.2f;
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f );
|
||||
|
||||
pParticle->m_uchStartSize = 1;
|
||||
pParticle->m_uchEndSize = random->RandomInt( 32, 48 );
|
||||
pParticle->m_uchStartAlpha = random->RandomInt( 128, 164 );
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
|
||||
int cScale = random->RandomInt( 192, 255 );
|
||||
pParticle->m_uchColor[0] = cScale;
|
||||
pParticle->m_uchColor[1] = cScale;
|
||||
pParticle->m_uchColor[2] = cScale;
|
||||
|
||||
Vector dir;
|
||||
QAngle ofsAngles;
|
||||
|
||||
ofsAngles.Random( -8.0f, 8.0f );
|
||||
ofsAngles += GetAbsAngles();
|
||||
|
||||
AngleVectors( ofsAngles, &dir );
|
||||
|
||||
if ( m_bUseMuzzlePoint )
|
||||
{
|
||||
dir.Negate();
|
||||
}
|
||||
|
||||
pParticle->m_vecVelocity = dir * random->RandomInt( 400, 800 );
|
||||
}
|
||||
|
||||
//Add muzzle effect
|
||||
pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, GetAbsOrigin() );
|
||||
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_flDieTime = 0.1f;
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta= random->RandomFloat( -4.0f, 4.0f );
|
||||
|
||||
pParticle->m_uchStartSize = 1;
|
||||
pParticle->m_uchEndSize = random->RandomInt( 8, 16 );
|
||||
pParticle->m_uchStartAlpha = random->RandomInt( 128, 255 );
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
|
||||
int cScale = random->RandomInt( 192, 255 );
|
||||
pParticle->m_uchColor[0] = cScale;
|
||||
pParticle->m_uchColor[1] = cScale;
|
||||
pParticle->m_uchColor[2] = cScale;
|
||||
|
||||
Vector dir;
|
||||
QAngle ofsAngles;
|
||||
|
||||
ofsAngles.Random( -64.0f, 64.0f );
|
||||
ofsAngles += GetAbsAngles();
|
||||
|
||||
AngleVectors( ofsAngles, &dir );
|
||||
|
||||
if ( m_bUseMuzzlePoint )
|
||||
{
|
||||
dir.Negate();
|
||||
}
|
||||
|
||||
pParticle->m_vecVelocity = dir * random->RandomInt( 32, 64 );
|
||||
}
|
||||
|
||||
//Add a wall effect if needed
|
||||
if ( hitWall )
|
||||
{
|
||||
AddExtinguisherDecal( tr );
|
||||
|
||||
Vector offDir;
|
||||
|
||||
offDir.Random( -16.0f, 16.0f );
|
||||
|
||||
pParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_MaterialHandle, ( tr.endpos + ( tr.plane.normal * 8.0f ) ) + offDir );
|
||||
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_flDieTime = 0.4f;
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta= random->RandomFloat( -2.0f, 2.0f );
|
||||
|
||||
pParticle->m_uchStartSize = random->RandomInt( 8, 16 );
|
||||
pParticle->m_uchEndSize = random->RandomInt( 24, 32 );
|
||||
pParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
|
||||
int cScale = random->RandomInt( 192, 255 );
|
||||
pParticle->m_uchColor[0] = cScale;
|
||||
pParticle->m_uchColor[1] = cScale;
|
||||
pParticle->m_uchColor[2] = cScale;
|
||||
|
||||
Vector rDir;
|
||||
|
||||
rDir = tr.plane.normal;
|
||||
rDir[0] += random->RandomFloat( -0.9f, 0.9f );
|
||||
rDir[1] += random->RandomFloat( -0.9f, 0.9f );
|
||||
rDir[2] += random->RandomFloat( -0.9f, 0.9f );
|
||||
|
||||
pParticle->m_vecVelocity = rDir * random->RandomInt( 32, 64 );
|
||||
}
|
||||
}
|
||||
|
||||
//Add small ember-like particles
|
||||
if ( random->RandomInt( 0, 1 ) == 0 )
|
||||
{
|
||||
m_pEmberEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
pParticle = (SimpleParticle *) m_pEmberEmitter->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[0], GetAbsOrigin() );
|
||||
|
||||
assert(pParticle);
|
||||
|
||||
if ( pParticle )
|
||||
{
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = 1.0f;
|
||||
|
||||
pParticle->m_flRoll = 0;
|
||||
pParticle->m_flRollDelta = 0;
|
||||
|
||||
pParticle->m_uchColor[0] = 255;
|
||||
pParticle->m_uchColor[1] = 255;
|
||||
pParticle->m_uchColor[2] = 255;
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
pParticle->m_uchStartSize = 1;
|
||||
pParticle->m_uchEndSize = 0;
|
||||
|
||||
Vector dir;
|
||||
QAngle ofsAngles;
|
||||
|
||||
ofsAngles.Random( -8.0f, 8.0f );
|
||||
ofsAngles += GetAbsAngles();
|
||||
|
||||
AngleVectors( ofsAngles, &dir );
|
||||
|
||||
if ( m_bUseMuzzlePoint )
|
||||
{
|
||||
dir.Negate();
|
||||
}
|
||||
|
||||
pParticle->m_vecVelocity = dir * random->RandomInt( 400, 800 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inner beam
|
||||
|
||||
CBeamSegDraw beamDraw;
|
||||
CBeamSeg seg;
|
||||
const int numPoints = 4;
|
||||
Vector beamPoints[numPoints];
|
||||
|
||||
beamPoints[0] = GetAbsOrigin();
|
||||
|
||||
// Create our beam points
|
||||
int i;
|
||||
for ( i = 0; i < numPoints; i++ )
|
||||
{
|
||||
beamPoints[i] = GetAbsOrigin() + ( shotDir * (32*i*i) );
|
||||
|
||||
beamPoints[i] += vRight * sin( gpGlobals->curtime * 4.0f ) * (2.0f*i);
|
||||
beamPoints[i] += vUp * sin( gpGlobals->curtime * 8.0f ) * (1.0f*i);
|
||||
beamPoints[i] += shotDir * sin( gpGlobals->curtime * (16.0f*i) ) * (1.0f*i);
|
||||
}
|
||||
|
||||
IMaterial *pMat = materials->FindMaterial( "particle/particle_smokegrenade", TEXTURE_GROUP_PARTICLE );
|
||||
|
||||
beamDraw.Start( numPoints, pMat );
|
||||
|
||||
//Setup and draw those points
|
||||
for( i = 0; i < numPoints; i++ )
|
||||
{
|
||||
float t = (float) i / (numPoints - 1);
|
||||
float color = 1.0f * (1.0f - t);
|
||||
|
||||
seg.m_vColor = Vector( color, color, color );
|
||||
seg.m_vPos = beamPoints[i];
|
||||
seg.m_flTexCoord = (float)i/(float)(numPoints-1) - ((gpGlobals->curtime - (int)gpGlobals->curtime) * 4.0f );
|
||||
seg.m_flWidth = 4.0f + ( (64.0f*t) * (fabs( sin( gpGlobals->curtime * 16.0f ) )) );
|
||||
seg.m_flAlpha = color;
|
||||
|
||||
beamDraw.NextSeg( &seg );
|
||||
}
|
||||
|
||||
beamDraw.End();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_ExtinguisherJet::DrawModel( int flags )
|
||||
{
|
||||
if ( m_bEmit == false )
|
||||
return 1;
|
||||
|
||||
Update( Helper_GetFrameTime() );
|
||||
|
||||
return 1;
|
||||
}
|
||||
249
game/client/hl2/c_func_tankmortar.cpp
Normal file
249
game/client/hl2/c_func_tankmortar.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "fx_quad.h"
|
||||
#include "fx.h"
|
||||
|
||||
class C_MortarShell : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_MortarShell, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
int DrawModel( int flags );
|
||||
|
||||
RenderGroup_t GetRenderGroup( void ) { return RENDER_GROUP_TRANSLUCENT_ENTITY; }
|
||||
|
||||
private:
|
||||
|
||||
void AddRisingParticles( float flPerc );
|
||||
void AddExplodingParticles( float flPerc );
|
||||
|
||||
inline float GetStartPerc( void );
|
||||
inline float GetEndPerc( void );
|
||||
|
||||
CSmartPtr<CSimpleEmitter> m_pEmitter;
|
||||
TimedEvent m_ParticleEvent;
|
||||
|
||||
float m_flLifespan;
|
||||
float m_flRadius;
|
||||
float m_flStarttime;
|
||||
Vector m_vecSurfaceNormal;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_MortarShell, DT_MortarShell, CMortarShell )
|
||||
RecvPropFloat( RECVINFO( m_flLifespan ) ),
|
||||
RecvPropFloat( RECVINFO( m_flRadius ) ),
|
||||
RecvPropVector( RECVINFO( m_vecSurfaceNormal ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MortarShell::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_flStarttime = gpGlobals->curtime;
|
||||
AddToLeafSystem( RENDER_GROUP_TRANSLUCENT_ENTITY );
|
||||
|
||||
m_pEmitter = CSimpleEmitter::Create( "C_EntityDissolve" );
|
||||
m_pEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
m_ParticleEvent.Init( 128 );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flPerc -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MortarShell::AddRisingParticles( float flPerc )
|
||||
{
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
Vector offset;
|
||||
float radius = m_flRadius * 0.25f * flPerc;
|
||||
|
||||
float val = RemapValClamped( gpGlobals->curtime, m_flStarttime, m_flStarttime + m_flLifespan, 0.0f, 1.0f );
|
||||
|
||||
float flCur = gpGlobals->frametime;
|
||||
|
||||
// Anime ground effects
|
||||
while ( m_ParticleEvent.NextEvent( flCur ) )
|
||||
{
|
||||
offset.x = random->RandomFloat( -radius, radius );
|
||||
offset.y = random->RandomFloat( -radius, radius );
|
||||
offset.z = random->RandomFloat( -8.0f, 8.0f );
|
||||
|
||||
offset += GetAbsOrigin();
|
||||
|
||||
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/spark" ), offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( 32.0f, 256.0f ) * Bias( val, 0.25f ) );
|
||||
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 4, 8 ) * flPerc;
|
||||
|
||||
sParticle->m_flDieTime = random->RandomFloat( 0.5f, 1.0f );
|
||||
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
|
||||
float alpha = 255 * flPerc;
|
||||
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f * flPerc, 8.0f * flPerc );
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flPerc -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_MortarShell::AddExplodingParticles( float flPerc )
|
||||
{
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
Vector offset;
|
||||
float radius = 48.0f * flPerc;
|
||||
|
||||
float flCur = gpGlobals->frametime;
|
||||
|
||||
// Anime ground effects
|
||||
while ( m_ParticleEvent.NextEvent( flCur ) )
|
||||
{
|
||||
offset.x = random->RandomFloat( -radius, radius );
|
||||
offset.y = random->RandomFloat( -radius, radius );
|
||||
offset.z = random->RandomFloat( -8.0f, 8.0f );
|
||||
|
||||
offset += GetAbsOrigin();
|
||||
|
||||
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/spark" ), offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_vecVelocity = RandomVector( -1.0f, 1.0f ) + Vector( 0, 0, 1 );
|
||||
sParticle->m_vecVelocity *= ( 750.0f * flPerc );
|
||||
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 2, 4 ) * flPerc;
|
||||
|
||||
sParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
|
||||
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
|
||||
float alpha = 255 * flPerc;
|
||||
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f * flPerc, 8.0f * flPerc );
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : inline float
|
||||
//-----------------------------------------------------------------------------
|
||||
inline float C_MortarShell::GetStartPerc( void )
|
||||
{
|
||||
float val = RemapValClamped( gpGlobals->curtime, m_flStarttime, m_flStarttime + m_flLifespan, 0.0f, 1.0f );
|
||||
|
||||
return ( Gain( val, 0.2f ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : inline float
|
||||
//-----------------------------------------------------------------------------
|
||||
inline float C_MortarShell::GetEndPerc( void )
|
||||
{
|
||||
float val = RemapValClamped( gpGlobals->curtime, m_flStarttime + m_flLifespan, m_flStarttime + m_flLifespan + 1.0f, 1.0f, 0.0f );
|
||||
|
||||
return ( Gain( val, 0.75f ) );
|
||||
}
|
||||
|
||||
#define ALPHA_MIN 0.0f
|
||||
#define ALPHA_MAX 1.0f
|
||||
|
||||
#define SCALE_MIN 8
|
||||
#define SCALE_MAX 200
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_MortarShell::DrawModel( int flags )
|
||||
{
|
||||
if ( gpGlobals->frametime <= 0.0f )
|
||||
return 0;
|
||||
|
||||
float flPerc;
|
||||
bool ending;
|
||||
|
||||
// See if we're in the beginning phase
|
||||
if ( gpGlobals->curtime < ( m_flStarttime + m_flLifespan ) )
|
||||
{
|
||||
flPerc = GetStartPerc();
|
||||
ending = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
flPerc = GetEndPerc();
|
||||
ending = true;
|
||||
}
|
||||
|
||||
float flAlpha = ALPHA_MIN + ( ( ALPHA_MAX - ALPHA_MIN ) * flPerc );
|
||||
float flScale = ( ending ) ? m_flRadius : ( (m_flRadius*0.1f)+ ( ( m_flRadius - (m_flRadius*0.1f) ) * flPerc ) );
|
||||
|
||||
// Do the ground effect
|
||||
FX_AddQuad( GetAbsOrigin() + ( m_vecSurfaceNormal * 2.0f ),
|
||||
m_vecSurfaceNormal,
|
||||
flScale,
|
||||
flScale,
|
||||
1.0f,
|
||||
flAlpha,
|
||||
flAlpha,
|
||||
1.0f,
|
||||
0,
|
||||
0,
|
||||
Vector( 1.0f, 1.0f, 1.0f ),
|
||||
0.0001f,
|
||||
"effects/combinemuzzle2_nocull",
|
||||
0 );
|
||||
|
||||
if ( !ending )
|
||||
{
|
||||
// Add extra effects on startup
|
||||
AddRisingParticles( flPerc );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add exploding particles after the impact
|
||||
AddExplodingParticles( flPerc );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
52
game/client/hl2/c_hl2_playerlocaldata.cpp
Normal file
52
game/client/hl2/c_hl2_playerlocaldata.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_hl2_playerlocaldata.h"
|
||||
#include "dt_recv.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
BEGIN_RECV_TABLE_NOBASE( C_HL2PlayerLocalData, DT_HL2Local )
|
||||
RecvPropFloat( RECVINFO(m_flSuitPower) ),
|
||||
RecvPropInt( RECVINFO(m_bZooming) ),
|
||||
RecvPropInt( RECVINFO(m_bitsActiveDevices) ),
|
||||
RecvPropInt( RECVINFO(m_iSquadMemberCount) ),
|
||||
RecvPropInt( RECVINFO(m_iSquadMedicCount) ),
|
||||
RecvPropBool( RECVINFO(m_fSquadInFollowMode) ),
|
||||
RecvPropBool( RECVINFO(m_bWeaponLowered) ),
|
||||
RecvPropEHandle( RECVINFO(m_hAutoAimTarget) ),
|
||||
RecvPropVector( RECVINFO(m_vecAutoAimPoint) ),
|
||||
RecvPropEHandle( RECVINFO(m_hLadder) ),
|
||||
RecvPropBool( RECVINFO(m_bDisplayReticle) ),
|
||||
RecvPropBool( RECVINFO(m_bStickyAutoAim) ),
|
||||
RecvPropBool( RECVINFO(m_bAutoAimTarget) ),
|
||||
#ifdef HL2_EPISODIC
|
||||
RecvPropFloat( RECVINFO(m_flFlashBattery) ),
|
||||
RecvPropVector( RECVINFO(m_vecLocatorOrigin) ),
|
||||
#endif
|
||||
END_RECV_TABLE()
|
||||
|
||||
BEGIN_PREDICTION_DATA_NO_BASE( C_HL2PlayerLocalData )
|
||||
DEFINE_PRED_FIELD( m_hLadder, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
|
||||
END_PREDICTION_DATA()
|
||||
|
||||
C_HL2PlayerLocalData::C_HL2PlayerLocalData()
|
||||
{
|
||||
m_flSuitPower = 0.0;
|
||||
m_bZooming = false;
|
||||
m_iSquadMemberCount = 0;
|
||||
m_iSquadMedicCount = 0;
|
||||
m_fSquadInFollowMode = false;
|
||||
m_bWeaponLowered = false;
|
||||
m_hLadder = NULL;
|
||||
#ifdef HL2_EPISODIC
|
||||
m_flFlashBattery = 0.0f;
|
||||
m_vecLocatorOrigin = vec3_origin;
|
||||
#endif
|
||||
}
|
||||
|
||||
55
game/client/hl2/c_hl2_playerlocaldata.h
Normal file
55
game/client/hl2/c_hl2_playerlocaldata.h
Normal file
@@ -0,0 +1,55 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $Workfile: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#if !defined( C_HL2_PLAYERLOCALDATA_H )
|
||||
#define C_HL2_PLAYERLOCALDATA_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#include "dt_recv.h"
|
||||
|
||||
#include "hl2/hl_movedata.h"
|
||||
|
||||
EXTERN_RECV_TABLE( DT_HL2Local );
|
||||
|
||||
|
||||
class C_HL2PlayerLocalData
|
||||
{
|
||||
public:
|
||||
DECLARE_PREDICTABLE();
|
||||
DECLARE_CLASS_NOBASE( C_HL2PlayerLocalData );
|
||||
DECLARE_EMBEDDED_NETWORKVAR();
|
||||
|
||||
C_HL2PlayerLocalData();
|
||||
|
||||
float m_flSuitPower;
|
||||
bool m_bZooming;
|
||||
int m_bitsActiveDevices;
|
||||
int m_iSquadMemberCount;
|
||||
int m_iSquadMedicCount;
|
||||
bool m_fSquadInFollowMode;
|
||||
bool m_bWeaponLowered;
|
||||
EHANDLE m_hAutoAimTarget;
|
||||
Vector m_vecAutoAimPoint;
|
||||
bool m_bDisplayReticle;
|
||||
bool m_bStickyAutoAim;
|
||||
bool m_bAutoAimTarget;
|
||||
#ifdef HL2_EPISODIC
|
||||
float m_flFlashBattery;
|
||||
Vector m_vecLocatorOrigin;
|
||||
#endif
|
||||
|
||||
// Ladder related data
|
||||
EHANDLE m_hLadder;
|
||||
LadderMove_t m_LadderMove;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
194
game/client/hl2/c_info_teleporter_countdown.cpp
Normal file
194
game/client/hl2/c_info_teleporter_countdown.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "c_vguiscreen.h"
|
||||
#include <vgui/IVGui.h>
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <vgui_controls/Label.h>
|
||||
#include "clientmode_hlnormal.h"
|
||||
#include "tier1/utllinkedlist.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Amount of time before breen teleports away
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_InfoTeleporterCountdown : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_InfoTeleporterCountdown, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
public:
|
||||
C_InfoTeleporterCountdown();
|
||||
~C_InfoTeleporterCountdown();
|
||||
|
||||
virtual bool ShouldDraw() { return false; }
|
||||
|
||||
private:
|
||||
bool m_bCountdownStarted;
|
||||
bool m_bDisabled;
|
||||
float m_flStartTime;
|
||||
float m_flTimeRemaining;
|
||||
|
||||
friend class CTeleportCountdownScreen;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Global list of teleporters
|
||||
//-----------------------------------------------------------------------------
|
||||
CUtlFixedLinkedList<C_InfoTeleporterCountdown *> g_InfoTeleporterCountdownList;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_InfoTeleporterCountdown, DT_InfoTeleporterCountdown, CInfoTeleporterCountdown )
|
||||
RecvPropInt( RECVINFO( m_bCountdownStarted ) ),
|
||||
RecvPropInt( RECVINFO( m_bDisabled ) ),
|
||||
RecvPropTime( RECVINFO( m_flStartTime ) ),
|
||||
RecvPropFloat( RECVINFO( m_flTimeRemaining ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor, destructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_InfoTeleporterCountdown::C_InfoTeleporterCountdown()
|
||||
{
|
||||
g_InfoTeleporterCountdownList.AddToTail( this );
|
||||
}
|
||||
|
||||
C_InfoTeleporterCountdown::~C_InfoTeleporterCountdown()
|
||||
{
|
||||
g_InfoTeleporterCountdownList.FindAndRemove( this );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// In-game vgui panel which shows the teleporter countdown
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
class CTeleportCountdownScreen : public CVGuiScreenPanel
|
||||
{
|
||||
DECLARE_CLASS( CTeleportCountdownScreen, CVGuiScreenPanel );
|
||||
|
||||
public:
|
||||
CTeleportCountdownScreen( vgui::Panel *parent, const char *panelName );
|
||||
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void OnTick();
|
||||
|
||||
private:
|
||||
vgui::Label *m_pTimeRemainingTitleLabel;
|
||||
vgui::Label *m_pTimeRemainingLabel;
|
||||
vgui::Label *m_pMalfunctionLabel;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Standard VGUI panel for objects
|
||||
//-----------------------------------------------------------------------------
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CTeleportCountdownScreen, "teleport_countdown_screen" );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor:
|
||||
//-----------------------------------------------------------------------------
|
||||
CTeleportCountdownScreen::CTeleportCountdownScreen( vgui::Panel *parent, const char *panelName )
|
||||
: BaseClass( parent, panelName, g_hVGuiCombineScheme )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Initialization
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CTeleportCountdownScreen::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
// Load all of the controls in
|
||||
if ( !BaseClass::Init(pKeyValues, pInitData) )
|
||||
return false;
|
||||
|
||||
// Make sure we get ticked...
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
|
||||
// Grab ahold of certain well-known controls
|
||||
// NOTE: it is valid for these controls to not exist!
|
||||
m_pTimeRemainingTitleLabel = dynamic_cast<vgui::Label*>(FindChildByName( "TimeRemainingTitle" ));
|
||||
m_pTimeRemainingLabel = dynamic_cast<vgui::Label*>(FindChildByName( "TimeRemaining" ));
|
||||
m_pMalfunctionLabel = dynamic_cast<vgui::Label*>( FindChildByName( "MalfunctionLabel" ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Frame-based update
|
||||
//-----------------------------------------------------------------------------
|
||||
void CTeleportCountdownScreen::OnTick()
|
||||
{
|
||||
BaseClass::OnTick();
|
||||
|
||||
// Find the active info teleporter countdown
|
||||
C_InfoTeleporterCountdown *pActiveCountdown = NULL;
|
||||
for ( int i = g_InfoTeleporterCountdownList.Head(); i != g_InfoTeleporterCountdownList.InvalidIndex();
|
||||
i = g_InfoTeleporterCountdownList.Next(i) )
|
||||
{
|
||||
if ( g_InfoTeleporterCountdownList[i]->m_bCountdownStarted )
|
||||
{
|
||||
pActiveCountdown = g_InfoTeleporterCountdownList[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !GetEntity() || !pActiveCountdown )
|
||||
{
|
||||
m_pTimeRemainingTitleLabel->SetVisible( false );
|
||||
m_pTimeRemainingLabel->SetVisible( false );
|
||||
m_pMalfunctionLabel->SetVisible( false );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Make the appropriate labels visible
|
||||
bool bMalfunction = pActiveCountdown->m_bDisabled;
|
||||
m_pTimeRemainingTitleLabel->SetVisible( !bMalfunction );
|
||||
m_pTimeRemainingLabel->SetVisible( !bMalfunction );
|
||||
|
||||
// This will make it flash
|
||||
m_pMalfunctionLabel->SetVisible( bMalfunction && (((int)(gpGlobals->curtime) & 0x1) == 0x1) );
|
||||
|
||||
// Update the time remaining
|
||||
if ( !bMalfunction )
|
||||
{
|
||||
char buf[32];
|
||||
if (m_pTimeRemainingLabel)
|
||||
{
|
||||
float dt = gpGlobals->curtime - pActiveCountdown->m_flStartTime;
|
||||
if ( dt < 0.0f )
|
||||
{
|
||||
dt = 0.0f;
|
||||
}
|
||||
|
||||
int nTimeRemaining = (int)(pActiveCountdown->m_flTimeRemaining - dt + 0.5f);
|
||||
if ( nTimeRemaining < 0 )
|
||||
{
|
||||
nTimeRemaining = 0;
|
||||
}
|
||||
|
||||
Q_snprintf( buf, sizeof( buf ), "%d", nTimeRemaining );
|
||||
m_pTimeRemainingLabel->SetText( buf );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
160
game/client/hl2/c_npc_antlionguard.cpp
Normal file
160
game/client/hl2/c_npc_antlionguard.cpp
Normal file
@@ -0,0 +1,160 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Client side antlion guard. Used to create dlight for the cave guard.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_ai_basenpc.h"
|
||||
#include "dlight.h"
|
||||
#include "iefx.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
#if HL2_EPISODIC
|
||||
// When enabled, add code to have the antlion bleed profusely as it is badly injured.
|
||||
#define ANTLIONGUARD_BLOOD_EFFECTS 2
|
||||
#endif
|
||||
|
||||
|
||||
class C_NPC_AntlionGuard : public C_AI_BaseNPC
|
||||
{
|
||||
public:
|
||||
C_NPC_AntlionGuard() {}
|
||||
|
||||
DECLARE_CLASS( C_NPC_AntlionGuard, C_AI_BaseNPC );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t type );
|
||||
virtual void ClientThink();
|
||||
|
||||
private:
|
||||
|
||||
bool m_bCavernBreed;
|
||||
bool m_bInCavern;
|
||||
dlight_t *m_dlight;
|
||||
|
||||
#if HL2_EPISODIC
|
||||
unsigned char m_iBleedingLevel; //< the version coming from the server
|
||||
unsigned char m_iPerformingBleedingLevel; //< the version we're currently performing (for comparison to one above)
|
||||
CNewParticleEffect *m_pBleedingFX;
|
||||
|
||||
/// update the hemorrhage particle effect
|
||||
virtual void UpdateBleedingPerformance( void );
|
||||
#endif
|
||||
|
||||
C_NPC_AntlionGuard( const C_NPC_AntlionGuard & );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Save/restore
|
||||
//-----------------------------------------------------------------------------
|
||||
BEGIN_DATADESC( C_NPC_AntlionGuard )
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_NPC_AntlionGuard, DT_NPC_AntlionGuard, CNPC_AntlionGuard)
|
||||
RecvPropBool( RECVINFO( m_bCavernBreed ) ),
|
||||
RecvPropBool( RECVINFO( m_bInCavern ) ),
|
||||
|
||||
#if ANTLIONGUARD_BLOOD_EFFECTS
|
||||
RecvPropInt( RECVINFO( m_iBleedingLevel ) ),
|
||||
#endif
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_AntlionGuard::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
if ( (type == DATA_UPDATE_CREATED) && m_bCavernBreed && m_bInCavern )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
|
||||
#if HL2_EPISODIC
|
||||
if (m_iBleedingLevel != m_iPerformingBleedingLevel)
|
||||
{
|
||||
UpdateBleedingPerformance();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if HL2_EPISODIC
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_AntlionGuard::UpdateBleedingPerformance()
|
||||
{
|
||||
// get my particles
|
||||
CParticleProperty * pProp = ParticleProp();
|
||||
|
||||
// squelch the prior effect if it exists
|
||||
if (m_pBleedingFX)
|
||||
{
|
||||
pProp->StopEmission(m_pBleedingFX);
|
||||
m_pBleedingFX = NULL;
|
||||
}
|
||||
|
||||
// kick off a new effect
|
||||
switch (m_iBleedingLevel)
|
||||
{
|
||||
case 1: // light bleeding
|
||||
{
|
||||
m_pBleedingFX = pProp->Create( "blood_antlionguard_injured_light", PATTACH_ABSORIGIN_FOLLOW );
|
||||
AssertMsg1( m_pBleedingFX, "Particle system couldn't make %s", "blood_antlionguard_injured_light" );
|
||||
if ( m_pBleedingFX )
|
||||
{
|
||||
pProp->AddControlPoint( m_pBleedingFX, 1, this, PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // severe bleeding
|
||||
{
|
||||
m_pBleedingFX = pProp->Create( "blood_antlionguard_injured_heavy", PATTACH_ABSORIGIN_FOLLOW );
|
||||
AssertMsg1( m_pBleedingFX, "Particle system couldn't make %s", "blood_antlionguard_injured_heavy" );
|
||||
if ( m_pBleedingFX )
|
||||
{
|
||||
pProp->AddControlPoint( m_pBleedingFX, 1, this, PATTACH_ABSORIGIN_FOLLOW );
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_iPerformingBleedingLevel = m_iBleedingLevel;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_AntlionGuard::ClientThink()
|
||||
{
|
||||
// update the dlight. (always done because clienthink only exists for cavernguard)
|
||||
if (!m_dlight)
|
||||
{
|
||||
m_dlight = effects->CL_AllocDlight( index );
|
||||
m_dlight->color.r = 220;
|
||||
m_dlight->color.g = 255;
|
||||
m_dlight->color.b = 80;
|
||||
m_dlight->radius = 180;
|
||||
m_dlight->minlight = 128.0 / 256.0f;
|
||||
m_dlight->flags = DLIGHT_NO_MODEL_ILLUMINATION;
|
||||
}
|
||||
|
||||
m_dlight->origin = GetAbsOrigin();
|
||||
// dl->die = gpGlobals->curtime + 0.1f;
|
||||
|
||||
BaseClass::ClientThink();
|
||||
}
|
||||
476
game/client/hl2/c_npc_combinegunship.cpp
Normal file
476
game/client/hl2/c_npc_combinegunship.cpp
Normal file
@@ -0,0 +1,476 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_basehelicopter.h"
|
||||
#include "fx_impact.h"
|
||||
#include "IEffects.h"
|
||||
#include "simple_keys.h"
|
||||
#include "fx_envelope.h"
|
||||
#include "fx_line.h"
|
||||
#include "iefx.h"
|
||||
#include "dlight.h"
|
||||
#include "c_sprite.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
#include <bitbuf.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define GUNSHIP_MSG_BIG_SHOT 1
|
||||
#define GUNSHIP_MSG_STREAKS 2
|
||||
#define GUNSHIP_MSG_DEAD 3
|
||||
|
||||
#define GUNSHIPFX_BIG_SHOT_TIME 3.0f
|
||||
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheGunshipFX )
|
||||
CLIENTEFFECT_MATERIAL( "sprites/bluelaser1" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Big belly shot FX
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class C_GunshipFX : public C_EnvelopeFX
|
||||
{
|
||||
public:
|
||||
typedef C_EnvelopeFX BaseClass;
|
||||
|
||||
C_GunshipFX();
|
||||
void Update( C_BaseEntity *pOwner, const Vector &targetPos );
|
||||
|
||||
// Returns the bounds relative to the origin (render bounds)
|
||||
virtual void GetRenderBounds( Vector& mins, Vector& maxs )
|
||||
{
|
||||
ClearBounds( mins, maxs );
|
||||
AddPointToBounds( m_worldPosition, mins, maxs );
|
||||
AddPointToBounds( m_targetPosition, mins, maxs );
|
||||
mins -= GetRenderOrigin();
|
||||
maxs -= GetRenderOrigin();
|
||||
}
|
||||
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
C_BaseEntity *m_pOwner;
|
||||
Vector m_targetPosition;
|
||||
Vector m_beamEndPosition;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_GunshipFX::C_GunshipFX( void )
|
||||
{
|
||||
m_pOwner = NULL;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
GUNSHIPFX_WARP_SCALE = 0,
|
||||
GUNSHIPFX_DARKNESS,
|
||||
GUNSHIPFX_FLARE_COLOR,
|
||||
GUNSHIPFX_FLARE_SIZE,
|
||||
|
||||
GUNSHIPFX_NARROW_BEAM_COLOR,
|
||||
GUNSHIPFX_NARROW_BEAM_SIZE,
|
||||
|
||||
GUNSHIPFX_WIDE_BEAM_COLOR,
|
||||
GUNSHIPFX_WIDE_BEAM_SIZE,
|
||||
|
||||
GUNSHIPFX_AFTERGLOW_COLOR,
|
||||
|
||||
GUNSHIPFX_WIDE_BEAM_LENGTH,
|
||||
|
||||
// must be last
|
||||
GUNSHIPFX_PARAMETERS,
|
||||
};
|
||||
|
||||
class CGunshipFXEnvelope
|
||||
{
|
||||
public:
|
||||
CGunshipFXEnvelope();
|
||||
|
||||
void AddKey( int parameterIndex, const CSimpleKeyInterp &key )
|
||||
{
|
||||
Assert( parameterIndex >= 0 && parameterIndex < GUNSHIPFX_PARAMETERS );
|
||||
|
||||
if ( parameterIndex >= 0 && parameterIndex < GUNSHIPFX_PARAMETERS )
|
||||
{
|
||||
m_parameters[parameterIndex].Insert( key );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CSimpleKeyList m_parameters[GUNSHIPFX_PARAMETERS];
|
||||
};
|
||||
|
||||
// NOTE: Beam widths are half-widths or radii, so this is a beam that represents a cylinder with 2" radius
|
||||
const float NARROW_BEAM_WIDTH = 32;
|
||||
const float WIDE_BEAM_WIDTH = 2;
|
||||
const float FLARE_SIZE = 128;
|
||||
const float DARK_SIZE = 16;
|
||||
const float AFTERGLOW_SIZE = 64;
|
||||
|
||||
CGunshipFXEnvelope::CGunshipFXEnvelope()
|
||||
{
|
||||
// Glow flare
|
||||
AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
|
||||
AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 0.5, KEY_SPLINE, 1 ) );
|
||||
AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 2.9, KEY_LINEAR, 1 ) );
|
||||
AddKey( GUNSHIPFX_FLARE_COLOR, CSimpleKeyInterp( 3.2, KEY_DECELERATE, 0 ) );
|
||||
|
||||
AddKey( GUNSHIPFX_FLARE_SIZE, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
|
||||
AddKey( GUNSHIPFX_FLARE_SIZE, CSimpleKeyInterp( 2.9, KEY_ACCELERATE, 1 ) );
|
||||
AddKey( GUNSHIPFX_FLARE_SIZE, CSimpleKeyInterp( 5.0, KEY_LINEAR, 1 ) );
|
||||
|
||||
// Ground beam
|
||||
AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0.0 ) );
|
||||
AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 2.5, KEY_SPLINE, 1.0 ) );
|
||||
AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 3.0, KEY_LINEAR, 1 ) );
|
||||
AddKey( GUNSHIPFX_NARROW_BEAM_COLOR, CSimpleKeyInterp( 3.2, KEY_ACCELERATE, 0 ) );
|
||||
|
||||
AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
|
||||
AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 2.5, KEY_SPLINE, 0.25 ) );
|
||||
AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 2.8, KEY_ACCELERATE, 1 ) );
|
||||
AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 3.0, KEY_ACCELERATE, 4 ) );
|
||||
AddKey( GUNSHIPFX_NARROW_BEAM_SIZE, CSimpleKeyInterp( 3.2, KEY_DECELERATE, 0 ) );
|
||||
|
||||
// Glow color on the ship
|
||||
AddKey( GUNSHIPFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 0.0, KEY_LINEAR, 0 ) );
|
||||
AddKey( GUNSHIPFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 3.0, KEY_LINEAR, 1 ) );
|
||||
AddKey( GUNSHIPFX_AFTERGLOW_COLOR, CSimpleKeyInterp( 5.0, KEY_SPLINE, 0 ) );
|
||||
}
|
||||
|
||||
CGunshipFXEnvelope g_GunshipCannonEnvelope;
|
||||
|
||||
static void ScaleColor( color32 &out, const color32 &in, float scale )
|
||||
{
|
||||
out.r = (byte)(int)((float)in.r * scale);
|
||||
out.g = (byte)(int)((float)in.g * scale);
|
||||
out.b = (byte)(int)((float)in.b * scale);
|
||||
out.a = (byte)(int)((float)in.a * scale);
|
||||
}
|
||||
|
||||
static void DrawSpriteTangentSpace( const Vector &vecOrigin, float flWidth, float flHeight, color32 color )
|
||||
{
|
||||
unsigned char pColor[4] = { color.r, color.g, color.b, color.a };
|
||||
|
||||
// Generate half-widths
|
||||
flWidth *= 0.5f;
|
||||
flHeight *= 0.5f;
|
||||
|
||||
// Compute direction vectors for the sprite
|
||||
Vector fwd, right( 1, 0, 0 ), up( 0, 1, 0 );
|
||||
VectorSubtract( CurrentViewOrigin(), vecOrigin, fwd );
|
||||
float flDist = VectorNormalize( fwd );
|
||||
if (flDist >= 1e-3)
|
||||
{
|
||||
CrossProduct( CurrentViewUp(), fwd, right );
|
||||
flDist = VectorNormalize( right );
|
||||
if (flDist >= 1e-3)
|
||||
{
|
||||
CrossProduct( fwd, right, up );
|
||||
}
|
||||
else
|
||||
{
|
||||
// In this case, fwd == g_vecVUp, it's right above or
|
||||
// below us in screen space
|
||||
CrossProduct( fwd, CurrentViewRight(), up );
|
||||
VectorNormalize( up );
|
||||
CrossProduct( up, fwd, right );
|
||||
}
|
||||
}
|
||||
|
||||
Vector left = -right;
|
||||
Vector down = -up;
|
||||
Vector back = -fwd;
|
||||
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
Vector point;
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh( );
|
||||
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
|
||||
|
||||
meshBuilder.Color4ubv (pColor);
|
||||
meshBuilder.TexCoord2f (0, 0, 1);
|
||||
VectorMA (vecOrigin, -flHeight, up, point);
|
||||
VectorMA (point, -flWidth, right, point);
|
||||
meshBuilder.TangentS3fv( left.Base() );
|
||||
meshBuilder.TangentT3fv( down.Base() );
|
||||
meshBuilder.Normal3fv( back.Base() );
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ubv (pColor);
|
||||
meshBuilder.TexCoord2f (0, 0, 0);
|
||||
VectorMA (vecOrigin, flHeight, up, point);
|
||||
VectorMA (point, -flWidth, right, point);
|
||||
meshBuilder.TangentS3fv( left.Base() );
|
||||
meshBuilder.TangentT3fv( down.Base() );
|
||||
meshBuilder.Normal3fv( back.Base() );
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ubv (pColor);
|
||||
meshBuilder.TexCoord2f (0, 1, 0);
|
||||
VectorMA (vecOrigin, flHeight, up, point);
|
||||
VectorMA (point, flWidth, right, point);
|
||||
meshBuilder.TangentS3fv( left.Base() );
|
||||
meshBuilder.TangentT3fv( down.Base() );
|
||||
meshBuilder.Normal3fv( back.Base() );
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ubv (pColor);
|
||||
meshBuilder.TexCoord2f (0, 1, 1);
|
||||
VectorMA (vecOrigin, -flHeight, up, point);
|
||||
VectorMA (point, flWidth, right, point);
|
||||
meshBuilder.TangentS3fv( left.Base() );
|
||||
meshBuilder.TangentT3fv( down.Base() );
|
||||
meshBuilder.Normal3fv( back.Base() );
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
|
||||
void Gunship_DrawSprite( const Vector &vecOrigin, float size, const color32 &color, bool glow )
|
||||
{
|
||||
if ( glow )
|
||||
{
|
||||
pixelvis_queryparams_t params;
|
||||
params.Init( vecOrigin );
|
||||
if ( PixelVisibility_FractionVisible( params, NULL ) <= 0.0f )
|
||||
return;
|
||||
}
|
||||
|
||||
DrawSpriteTangentSpace( vecOrigin, size, size, color );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : int -
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_GunshipFX::DrawModel( int )
|
||||
{
|
||||
static color32 white = {255,255,255,255};
|
||||
Vector params[GUNSHIPFX_PARAMETERS];
|
||||
bool hasParam[GUNSHIPFX_PARAMETERS];
|
||||
|
||||
if ( !m_active )
|
||||
return 1;
|
||||
|
||||
C_BaseEntity *ent = cl_entitylist->GetEnt( m_entityIndex );
|
||||
if ( ent )
|
||||
{
|
||||
QAngle angles;
|
||||
ent->GetAttachment( m_attachment, m_worldPosition, angles );
|
||||
}
|
||||
|
||||
Vector test;
|
||||
m_t += gpGlobals->frametime;
|
||||
if ( m_tMax > 0 )
|
||||
{
|
||||
m_t = clamp( m_t, 0, m_tMax );
|
||||
m_beamEndPosition = m_worldPosition;
|
||||
}
|
||||
float t = m_t;
|
||||
|
||||
bool hasAny = false;
|
||||
memset( hasParam, 0, sizeof(hasParam) );
|
||||
for ( int i = 0; i < GUNSHIPFX_PARAMETERS; i++ )
|
||||
{
|
||||
hasParam[i] = g_GunshipCannonEnvelope.m_parameters[i].Interp( params[i], t );
|
||||
hasAny = hasAny || hasParam[i];
|
||||
}
|
||||
|
||||
// draw the narrow beam
|
||||
if ( hasParam[GUNSHIPFX_NARROW_BEAM_COLOR] && hasParam[GUNSHIPFX_NARROW_BEAM_SIZE] )
|
||||
{
|
||||
IMaterial *pMat = materials->FindMaterial( "sprites/bluelaser1", TEXTURE_GROUP_CLIENT_EFFECTS );
|
||||
float width = NARROW_BEAM_WIDTH * params[GUNSHIPFX_NARROW_BEAM_SIZE].x;
|
||||
color32 color;
|
||||
float bright = params[GUNSHIPFX_NARROW_BEAM_COLOR].x;
|
||||
ScaleColor( color, white, bright );
|
||||
|
||||
//Gunship_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color );
|
||||
FX_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color );
|
||||
}
|
||||
|
||||
// glowy blue flare sprite
|
||||
if ( hasParam[GUNSHIPFX_FLARE_COLOR] && hasParam[GUNSHIPFX_FLARE_SIZE] )
|
||||
{
|
||||
IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
|
||||
float size = FLARE_SIZE * params[GUNSHIPFX_FLARE_SIZE].x;
|
||||
color32 color;
|
||||
float bright = params[GUNSHIPFX_FLARE_COLOR].x;
|
||||
ScaleColor( color, white, bright );
|
||||
color.a = (int)(255 * params[GUNSHIPFX_DARKNESS].x);
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
pRenderContext->Bind( pMat, (IClientRenderable*)this );
|
||||
Gunship_DrawSprite( m_worldPosition, size, color, true );
|
||||
}
|
||||
|
||||
if ( hasParam[GUNSHIPFX_AFTERGLOW_COLOR] )
|
||||
{
|
||||
// Muzzle effect
|
||||
dlight_t *dl = effects->CL_AllocDlight( m_entityIndex );
|
||||
dl->origin = m_worldPosition;
|
||||
dl->color.r = 40*params[GUNSHIPFX_AFTERGLOW_COLOR].x;
|
||||
dl->color.g = 60*params[GUNSHIPFX_AFTERGLOW_COLOR].x;
|
||||
dl->color.b = 255*params[GUNSHIPFX_AFTERGLOW_COLOR].x;
|
||||
dl->color.exponent = 5;
|
||||
dl->radius = 128.0f;
|
||||
dl->die = gpGlobals->curtime + 0.001;
|
||||
}
|
||||
|
||||
if ( m_t >= 4.0 && !hasAny )
|
||||
{
|
||||
EffectShutdown();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pOwner -
|
||||
// &targetPos -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_GunshipFX::Update( C_BaseEntity *pOwner, const Vector &targetPos )
|
||||
{
|
||||
BaseClass::Update();
|
||||
|
||||
m_pOwner = pOwner;
|
||||
|
||||
if ( m_active )
|
||||
{
|
||||
m_targetPosition = targetPos;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gunship
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class C_CombineGunship : public C_BaseHelicopter
|
||||
{
|
||||
DECLARE_CLASS( C_CombineGunship, C_BaseHelicopter );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_CombineGunship( void ) {}
|
||||
|
||||
virtual ~C_CombineGunship( void )
|
||||
{
|
||||
m_cannonFX.EffectShutdown();
|
||||
}
|
||||
|
||||
C_GunshipFX m_cannonFX;
|
||||
Vector m_vecHitPos;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : length -
|
||||
// *data -
|
||||
// Output : void
|
||||
//-----------------------------------------------------------------------------
|
||||
void ReceiveMessage( int classID, bf_read &msg )
|
||||
{
|
||||
if ( classID != GetClientClass()->m_ClassID )
|
||||
{
|
||||
// message is for subclass
|
||||
BaseClass::ReceiveMessage( classID, msg );
|
||||
return;
|
||||
}
|
||||
|
||||
int messageType = msg.ReadByte();
|
||||
switch( messageType )
|
||||
{
|
||||
case GUNSHIP_MSG_STREAKS:
|
||||
{
|
||||
Vector pos;
|
||||
msg.ReadBitVec3Coord( pos );
|
||||
m_cannonFX.SetRenderOrigin( pos );
|
||||
m_cannonFX.EffectInit( entindex(), LookupAttachment( "BellyGun" ) );
|
||||
m_cannonFX.LimitTime( GUNSHIPFX_BIG_SHOT_TIME );
|
||||
}
|
||||
break;
|
||||
|
||||
case GUNSHIP_MSG_BIG_SHOT:
|
||||
{
|
||||
Vector tmp;
|
||||
msg.ReadBitVec3Coord( tmp );
|
||||
m_cannonFX.SetTime( GUNSHIPFX_BIG_SHOT_TIME );
|
||||
m_cannonFX.LimitTime( 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case GUNSHIP_MSG_DEAD:
|
||||
{
|
||||
m_cannonFX.EffectShutdown();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
m_cannonFX.Update( this, m_vecHitPos );
|
||||
}
|
||||
|
||||
virtual RenderGroup_t GetRenderGroup()
|
||||
{
|
||||
if ( hl2_episodic.GetBool() == true )
|
||||
{
|
||||
return RENDER_GROUP_TWOPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return BaseClass::GetRenderGroup();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
C_CombineGunship( const C_CombineGunship & ) {}
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_CombineGunship, DT_CombineGunship, CNPC_CombineGunship )
|
||||
RecvPropVector(RECVINFO(m_vecHitPos)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle gunship impacts
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImpactGunshipCallback( const CEffectData &data )
|
||||
{
|
||||
trace_t tr;
|
||||
Vector vecOrigin, vecStart, vecShotDir;
|
||||
int iMaterial, iDamageType, iHitbox;
|
||||
short nSurfaceProp;
|
||||
C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox );
|
||||
|
||||
if ( !pEntity )
|
||||
return;
|
||||
|
||||
// If we hit, perform our custom effects and play the sound
|
||||
if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr ) )
|
||||
{
|
||||
// Check for custom effects based on the Decal index
|
||||
PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, 3 );
|
||||
}
|
||||
|
||||
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "ImpactGunship", ImpactGunshipCallback );
|
||||
|
||||
386
game/client/hl2/c_npc_hydra.cpp
Normal file
386
game/client/hl2/c_npc_hydra.cpp
Normal file
@@ -0,0 +1,386 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "bone_setup.h"
|
||||
#include "c_ai_basenpc.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "soundinfo.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_NPC_Hydra : public C_AI_BaseNPC
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_NPC_Hydra, C_AI_BaseNPC );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_INTERPOLATION();
|
||||
|
||||
C_NPC_Hydra();
|
||||
virtual ~C_NPC_Hydra();
|
||||
|
||||
// model specific
|
||||
virtual void OnLatchInterpolatedVariables( int flags );
|
||||
virtual bool SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime );
|
||||
virtual void StandardBlendingRules( Vector pos[], Quaternion q[], float currentTime, int boneMask );
|
||||
|
||||
void CalcBoneChain( Vector pos[], const Vector chain[] );
|
||||
void CalcBoneAngles( const Vector pos[], Quaternion q[] );
|
||||
|
||||
virtual bool GetSoundSpatialization( SpatializationInfo_t& info );
|
||||
|
||||
virtual void ResetLatched();
|
||||
|
||||
#define CHAIN_LINKS 32
|
||||
|
||||
bool m_bNewChain;
|
||||
int m_fLatchFlags;
|
||||
Vector m_vecChain[CHAIN_LINKS];
|
||||
|
||||
Vector m_vecHeadDir;
|
||||
CInterpolatedVar< Vector > m_iv_vecHeadDir;
|
||||
|
||||
//Vector m_vecInterpHeadDir;
|
||||
|
||||
float m_flRelaxedLength;
|
||||
|
||||
Vector *m_vecPos; // current animation
|
||||
CInterpolatedVar< Vector > *m_iv_vecPos;
|
||||
|
||||
int m_numHydraBones;
|
||||
float *m_boneLength;
|
||||
|
||||
float m_maxPossibleLength;
|
||||
|
||||
private:
|
||||
C_NPC_Hydra( const C_NPC_Hydra & ); // not defined, not accessible
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_NPC_Hydra, DT_NPC_Hydra, CNPC_Hydra)
|
||||
RecvPropVector ( RECVINFO( m_vecChain[0] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[1] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[2] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[3] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[4] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[5] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[6] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[7] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[8] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[9] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[10] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[11] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[12] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[13] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[14] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[15] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[16] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[17] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[18] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[19] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[20] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[21] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[22] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[23] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[24] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[25] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[26] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[27] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[28] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[29] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[30] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecChain[31] ) ),
|
||||
RecvPropVector ( RECVINFO( m_vecHeadDir ) ),
|
||||
RecvPropFloat ( RECVINFO( m_flRelaxedLength ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
C_NPC_Hydra::C_NPC_Hydra() : m_iv_vecHeadDir( "C_NPC_Hydra::m_iv_vecHeadDir" )
|
||||
{
|
||||
AddVar( &m_vecHeadDir, &m_iv_vecHeadDir, LATCH_ANIMATION_VAR );
|
||||
|
||||
m_numHydraBones = 0;
|
||||
m_boneLength = NULL;
|
||||
m_maxPossibleLength = 1;
|
||||
m_vecPos = NULL;
|
||||
m_iv_vecPos = NULL;
|
||||
}
|
||||
|
||||
|
||||
C_NPC_Hydra::~C_NPC_Hydra()
|
||||
{
|
||||
delete m_boneLength;
|
||||
delete m_vecPos;
|
||||
delete[] m_iv_vecPos;
|
||||
m_iv_vecPos = NULL;
|
||||
}
|
||||
|
||||
void C_NPC_Hydra::OnLatchInterpolatedVariables( int flags )
|
||||
{
|
||||
m_bNewChain = true;
|
||||
m_fLatchFlags = flags;
|
||||
|
||||
BaseClass::OnLatchInterpolatedVariables( flags );
|
||||
}
|
||||
|
||||
void C_NPC_Hydra::ResetLatched()
|
||||
{
|
||||
for (int i = 0; i < m_numHydraBones; i++)
|
||||
{
|
||||
m_iv_vecPos[i].Reset();
|
||||
}
|
||||
|
||||
BaseClass::ResetLatched();
|
||||
}
|
||||
|
||||
bool C_NPC_Hydra::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime )
|
||||
{
|
||||
return BaseClass::SetupBones( pBoneToWorldOut, nMaxBones, boneMask, currentTime );
|
||||
}
|
||||
|
||||
|
||||
void C_NPC_Hydra::StandardBlendingRules( Vector pos[], Quaternion q[], float currentTime, int boneMask )
|
||||
{
|
||||
VPROF( "C_NPC_Hydra::StandardBlendingRules" );
|
||||
|
||||
studiohdr_t *hdr = GetModelPtr();
|
||||
if ( !hdr )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
// check for changing model memory requirements
|
||||
bool bNewlyInited = false;
|
||||
if (m_numHydraBones != hdr->numbones)
|
||||
{
|
||||
m_numHydraBones = hdr->numbones;
|
||||
|
||||
// build root animation
|
||||
float poseparam[MAXSTUDIOPOSEPARAM];
|
||||
for (i = 0; i < hdr->GetNumPoseParameters(); i++)
|
||||
{
|
||||
poseparam[i] = 0;
|
||||
}
|
||||
CalcPose( hdr, NULL, pos, q, 0.0f, 0.0f, poseparam, BONE_USED_BY_ANYTHING );
|
||||
|
||||
// allocate arrays
|
||||
if (m_boneLength)
|
||||
{
|
||||
delete[] m_boneLength;
|
||||
}
|
||||
m_boneLength = new float [m_numHydraBones];
|
||||
|
||||
if (m_vecPos)
|
||||
{
|
||||
delete[] m_vecPos;
|
||||
}
|
||||
m_vecPos = new Vector [m_numHydraBones];
|
||||
|
||||
if (m_iv_vecPos)
|
||||
{
|
||||
delete m_iv_vecPos;
|
||||
}
|
||||
m_iv_vecPos = new CInterpolatedVar< Vector >[m_numHydraBones];
|
||||
for ( i = 0; i < m_numHydraBones; i++ )
|
||||
{
|
||||
m_iv_vecPos[ i ].Setup( &m_vecPos[ i ], LATCH_SIMULATION_VAR | EXCLUDE_AUTO_LATCH | EXCLUDE_AUTO_INTERPOLATE );
|
||||
}
|
||||
|
||||
// calc models bone lengths
|
||||
m_maxPossibleLength = 0;
|
||||
for (i = 0; i < m_numHydraBones-1; i++)
|
||||
{
|
||||
m_boneLength[i] = (pos[i+1] - pos[i]).Length();
|
||||
m_maxPossibleLength += m_boneLength[i];
|
||||
}
|
||||
m_boneLength[i] = 0.0f;
|
||||
|
||||
bNewlyInited = true;
|
||||
}
|
||||
|
||||
// calc new bone setup if networked.
|
||||
if (m_bNewChain)
|
||||
{
|
||||
CalcBoneChain( m_vecPos, m_vecChain );
|
||||
for (i = 0; i < m_numHydraBones; i++)
|
||||
{
|
||||
// debugoverlay->AddLineOverlay( m_vecPos[i], m_vecPos[i<m_numHydraBones-1?i+1:m_numHydraBones-1], 0, 255, 0, false, 0.1 );
|
||||
m_vecPos[i] = m_vecPos[i] - GetAbsOrigin();
|
||||
|
||||
if ( m_fLatchFlags & LATCH_SIMULATION_VAR )
|
||||
{
|
||||
m_iv_vecPos[i].NoteChanged( currentTime, true );
|
||||
}
|
||||
}
|
||||
m_bNewChain = false;
|
||||
}
|
||||
|
||||
// if just allocated, initialize bones
|
||||
if (bNewlyInited)
|
||||
{
|
||||
|
||||
for (i = 0; i < m_numHydraBones; i++)
|
||||
{
|
||||
m_iv_vecPos[i].Reset();
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < m_numHydraBones; i++)
|
||||
{
|
||||
m_iv_vecPos[i].Interpolate( currentTime );
|
||||
pos[ i ] = m_vecPos[ i ];
|
||||
}
|
||||
|
||||
// calculate bone angles
|
||||
CalcBoneAngles( pos, q );
|
||||
|
||||
// rotate the last bone of the hydra 90 degrees since it's oriented differently than the others
|
||||
Quaternion qTmp;
|
||||
AngleQuaternion( QAngle( 0, -90, 0) , qTmp );
|
||||
QuaternionMult( q[m_numHydraBones - 1], qTmp, q[m_numHydraBones - 1] );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Fits skeleton of hydra to the variable segment length "chain" array
|
||||
// Adjusts overall hydra so that "m_flRelaxedLength" of texture fits over
|
||||
// the actual length of the chain
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_NPC_Hydra::CalcBoneChain( Vector pos[], const Vector chain[] )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// Find the dist chain link that's not zero length
|
||||
i = CHAIN_LINKS-1;
|
||||
while (i > 0)
|
||||
{
|
||||
if ((chain[i] - chain[i-1]).LengthSqr() > 0.0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
// initialize the last bone to the last bone
|
||||
j = m_numHydraBones - 1;
|
||||
|
||||
// clamp length
|
||||
float totalLength = 0;
|
||||
for (int k = i; k > 0; k--)
|
||||
{
|
||||
// debugoverlay->AddLineOverlay( chain[k], chain[k-1], 255, 255, 255, false, 0 );
|
||||
totalLength += (chain[k] - chain[k-1]).Length();
|
||||
}
|
||||
totalLength = clamp( totalLength, 1.0, m_maxPossibleLength );
|
||||
float scale = m_flRelaxedLength / totalLength;
|
||||
|
||||
// starting from the head, fit the hydra skeleton onto the chain spline
|
||||
float dist = -16;
|
||||
while (j >= 0 && i > 0)
|
||||
{
|
||||
// debugoverlay->AddLineOverlay( chain[i], chain[i-1], 255, 255, 255, false, 0 );
|
||||
float dt = (chain[i] - chain[i-1]).Length() * scale;
|
||||
float dx = dt;
|
||||
while (j >= 0 && dist + dt >= m_boneLength[j])
|
||||
{
|
||||
float s = (dx - (dt - (m_boneLength[j] - dist))) / dx;
|
||||
|
||||
if (s < 0 || s > 1.)
|
||||
s = 0;
|
||||
// pos[j] = chain[i] * (1 - s) + chain[i-1] * s;
|
||||
Catmull_Rom_Spline( chain[(i<CHAIN_LINKS-1)?i+1:CHAIN_LINKS-1], chain[i], chain[(i>0)?i-1:0], chain[(i>1)?i-2:0], s, pos[j] );
|
||||
// debugoverlay->AddLineOverlay( pos[j], chain[i], 0, 255, 0, false, 0 );
|
||||
// debugoverlay->AddLineOverlay( pos[j], chain[i-1], 0, 255, 0, false, 0 );
|
||||
|
||||
dt = dt - (m_boneLength[j] - dist);
|
||||
j--;
|
||||
dist = 0;
|
||||
}
|
||||
dist += dt;
|
||||
i--;
|
||||
}
|
||||
|
||||
while (j >= 0)
|
||||
{
|
||||
pos[j] = chain[0];
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Minimize the amount of twist between bone segments
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void C_NPC_Hydra::CalcBoneAngles( const Vector pos[], Quaternion q[] )
|
||||
{
|
||||
int i;
|
||||
matrix3x4_t bonematrix;
|
||||
|
||||
for (i = m_numHydraBones - 1; i >= 0; i--)
|
||||
{
|
||||
Vector forward;
|
||||
Vector left2;
|
||||
|
||||
if (i != m_numHydraBones - 1)
|
||||
{
|
||||
QuaternionMatrix( q[i+1], bonematrix );
|
||||
MatrixGetColumn( bonematrix, 1, left2 );
|
||||
|
||||
forward = (pos[i+1] - pos[i]) /* + (pos[i] - pos[i-1])*/;
|
||||
float length = VectorNormalize( forward );
|
||||
if (length == 0.0)
|
||||
{
|
||||
q[i] = q[i+1];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forward = m_vecHeadDir;
|
||||
VectorNormalize( forward );
|
||||
|
||||
VectorMatrix( forward, bonematrix );
|
||||
MatrixGetColumn( bonematrix, 1, left2 );
|
||||
}
|
||||
|
||||
Vector up = CrossProduct( forward, left2 );
|
||||
VectorNormalize( up );
|
||||
|
||||
Vector left = CrossProduct( up, forward );
|
||||
|
||||
MatrixSetColumn( forward, 0, bonematrix );
|
||||
MatrixSetColumn( left, 1, bonematrix );
|
||||
MatrixSetColumn( up, 2, bonematrix );
|
||||
|
||||
// MatrixQuaternion( bonematrix, q[i] );
|
||||
QAngle angles;
|
||||
MatrixAngles( bonematrix, angles );
|
||||
AngleQuaternion( angles, q[i] );
|
||||
}
|
||||
}
|
||||
|
||||
bool C_NPC_Hydra::GetSoundSpatialization( SpatializationInfo_t& info )
|
||||
{
|
||||
bool bret = BaseClass::GetSoundSpatialization( info );
|
||||
// Default things it's audible, put it at a better spot?
|
||||
if ( bret )
|
||||
{
|
||||
// TODO: Note, this is where you could override the sound position and orientation and use
|
||||
// an attachment points position as the sound source
|
||||
// You might have to issue C_BaseAnimating::AllowBoneAccess( true, false ); to allow
|
||||
// bone setup during sound spatialization if you run into asserts...
|
||||
}
|
||||
|
||||
return bret;
|
||||
}
|
||||
|
||||
182
game/client/hl2/c_npc_manhack.cpp
Normal file
182
game/client/hl2/c_npc_manhack.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_ai_basenpc.h"
|
||||
#include "soundenvelope.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class C_NPC_Manhack : public C_AI_BaseNPC
|
||||
{
|
||||
public:
|
||||
C_NPC_Manhack() {}
|
||||
|
||||
DECLARE_CLASS( C_NPC_Manhack, C_AI_BaseNPC );
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
// Purpose: Start the manhack's engine sound.
|
||||
virtual void OnDataChanged( DataUpdateType_t type );
|
||||
virtual void UpdateOnRemove( void );
|
||||
virtual void OnRestore();
|
||||
|
||||
private:
|
||||
C_NPC_Manhack( const C_NPC_Manhack & );
|
||||
|
||||
// Purpose: Start + stop the manhack's engine sound.
|
||||
void SoundInit( void );
|
||||
void SoundShutdown( void );
|
||||
|
||||
CSoundPatch *m_pEngineSound1;
|
||||
CSoundPatch *m_pEngineSound2;
|
||||
CSoundPatch *m_pBladeSound;
|
||||
|
||||
int m_nEnginePitch1;
|
||||
int m_nEnginePitch2;
|
||||
float m_flEnginePitch1Time;
|
||||
float m_flEnginePitch2Time;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Save/restore
|
||||
//-----------------------------------------------------------------------------
|
||||
BEGIN_DATADESC( C_NPC_Manhack )
|
||||
|
||||
// DEFINE_SOUNDPATCH( m_pEngineSound1 ),
|
||||
// DEFINE_SOUNDPATCH( m_pEngineSound2 ),
|
||||
// DEFINE_SOUNDPATCH( m_pBladeSound ),
|
||||
|
||||
// DEFINE_FIELD( m_nEnginePitch1, FIELD_INTEGER ),
|
||||
// DEFINE_FIELD( m_nEnginePitch2, FIELD_INTEGER ),
|
||||
// DEFINE_FIELD( m_flEnginePitch1Time, FIELD_FLOAT ),
|
||||
// DEFINE_FIELD( m_flEnginePitch2Time, FIELD_FLOAT ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_NPC_Manhack, DT_NPC_Manhack, CNPC_Manhack)
|
||||
RecvPropIntWithMinusOneFlag(RECVINFO(m_nEnginePitch1)),
|
||||
RecvPropFloat(RECVINFO(m_flEnginePitch1Time)),
|
||||
RecvPropIntWithMinusOneFlag(RECVINFO(m_nEnginePitch2)),
|
||||
RecvPropFloat(RECVINFO(m_flEnginePitch2Time)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Start the manhack's engine sound.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Manhack::OnDataChanged( DataUpdateType_t type )
|
||||
{
|
||||
BaseClass::OnDataChanged( type );
|
||||
|
||||
if (( m_nEnginePitch1 < 0 ) || ( m_nEnginePitch2 < 0 ) )
|
||||
{
|
||||
SoundShutdown();
|
||||
}
|
||||
else
|
||||
{
|
||||
SoundInit();
|
||||
if ( m_pEngineSound1 && m_pEngineSound2 )
|
||||
{
|
||||
float dt = ( m_flEnginePitch1Time >= gpGlobals->curtime ) ? m_flEnginePitch1Time - gpGlobals->curtime : 0.0f;
|
||||
CSoundEnvelopeController::GetController().SoundChangePitch( m_pEngineSound1, m_nEnginePitch1, dt );
|
||||
dt = ( m_flEnginePitch2Time >= gpGlobals->curtime ) ? m_flEnginePitch2Time - gpGlobals->curtime : 0.0f;
|
||||
CSoundEnvelopeController::GetController().SoundChangePitch( m_pEngineSound2, m_nEnginePitch2, dt );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Restore
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Manhack::OnRestore()
|
||||
{
|
||||
BaseClass::OnRestore();
|
||||
SoundInit();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Start the manhack's engine sound.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Manhack::UpdateOnRemove( void )
|
||||
{
|
||||
BaseClass::UpdateOnRemove();
|
||||
SoundShutdown();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Start the manhack's engine sound.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Manhack::SoundInit( void )
|
||||
{
|
||||
if (( m_nEnginePitch1 < 0 ) || ( m_nEnginePitch2 < 0 ) )
|
||||
return;
|
||||
|
||||
// play an engine start sound!!
|
||||
CPASAttenuationFilter filter( this );
|
||||
|
||||
// Bring up the engine looping sound.
|
||||
if( !m_pEngineSound1 )
|
||||
{
|
||||
m_pEngineSound1 = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), "NPC_Manhack.EngineSound1" );
|
||||
CSoundEnvelopeController::GetController().Play( m_pEngineSound1, 0.0, m_nEnginePitch1 );
|
||||
CSoundEnvelopeController::GetController().SoundChangeVolume( m_pEngineSound1, 0.7, 2.0 );
|
||||
}
|
||||
|
||||
if( !m_pEngineSound2 )
|
||||
{
|
||||
m_pEngineSound2 = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), "NPC_Manhack.EngineSound2" );
|
||||
CSoundEnvelopeController::GetController().Play( m_pEngineSound2, 0.0, m_nEnginePitch2 );
|
||||
CSoundEnvelopeController::GetController().SoundChangeVolume( m_pEngineSound2, 0.7, 2.0 );
|
||||
}
|
||||
|
||||
if( !m_pBladeSound )
|
||||
{
|
||||
m_pBladeSound = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), "NPC_Manhack.BladeSound" );
|
||||
CSoundEnvelopeController::GetController().Play( m_pBladeSound, 0.0, m_nEnginePitch1 );
|
||||
CSoundEnvelopeController::GetController().SoundChangeVolume( m_pBladeSound, 0.7, 2.0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_NPC_Manhack::SoundShutdown(void)
|
||||
{
|
||||
// Kill the engine!
|
||||
if ( m_pEngineSound1 )
|
||||
{
|
||||
CSoundEnvelopeController::GetController().SoundDestroy( m_pEngineSound1 );
|
||||
m_pEngineSound1 = NULL;
|
||||
}
|
||||
|
||||
// Kill the engine!
|
||||
if ( m_pEngineSound2 )
|
||||
{
|
||||
CSoundEnvelopeController::GetController().SoundDestroy( m_pEngineSound2 );
|
||||
m_pEngineSound2 = NULL;
|
||||
}
|
||||
|
||||
// Kill the blade!
|
||||
if ( m_pBladeSound )
|
||||
{
|
||||
CSoundEnvelopeController::GetController().SoundDestroy( m_pBladeSound );
|
||||
m_pBladeSound = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
174
game/client/hl2/c_npc_rollermine.cpp
Normal file
174
game/client/hl2/c_npc_rollermine.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_ai_basenpc.h"
|
||||
#include "iviewrender_beams.h"
|
||||
#include "beam_shared.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "model_types.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
#include "beamdraw.h"
|
||||
|
||||
class C_RollerMine : public C_AI_BaseNPC
|
||||
{
|
||||
DECLARE_CLASS( C_RollerMine, C_AI_BaseNPC );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_RollerMine( void ) {}
|
||||
|
||||
int DrawModel( int flags );
|
||||
|
||||
RenderGroup_t GetRenderGroup( void )
|
||||
{
|
||||
if ( m_bIsOpen )
|
||||
return RENDER_GROUP_TRANSLUCENT_ENTITY;
|
||||
else
|
||||
return RENDER_GROUP_OPAQUE_ENTITY;
|
||||
}
|
||||
|
||||
private:
|
||||
C_RollerMine( const C_RollerMine & ) {}
|
||||
|
||||
bool m_bIsOpen;
|
||||
float m_flActiveTime;
|
||||
bool m_bHackedByAlyx;
|
||||
bool m_bPowerDown;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_RollerMine, DT_RollerMine, CNPC_RollerMine )
|
||||
RecvPropInt( RECVINFO( m_bIsOpen ) ),
|
||||
RecvPropFloat( RECVINFO( m_flActiveTime ) ),
|
||||
RecvPropInt( RECVINFO( m_bHackedByAlyx ) ),
|
||||
RecvPropInt( RECVINFO( m_bPowerDown ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
#define NUM_ATTACHMENTS 11
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_RollerMine::DrawModel( int flags )
|
||||
{
|
||||
if ( m_bIsOpen && m_flActiveTime <= gpGlobals->curtime )
|
||||
{
|
||||
float scale = random->RandomFloat( 4.0f, 6.0f );
|
||||
|
||||
if ( gpGlobals->frametime != 0 )
|
||||
{
|
||||
// Inner beams
|
||||
BeamInfo_t beamInfo;
|
||||
|
||||
beamInfo.m_vecStart = GetAbsOrigin();
|
||||
Vector offset = RandomVector( -6*scale, 2*scale );
|
||||
|
||||
offset += Vector(2,2,2) * scale;
|
||||
beamInfo.m_vecEnd = GetAbsOrigin() + offset;
|
||||
|
||||
beamInfo.m_pStartEnt= cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
|
||||
beamInfo.m_pEndEnt = beamInfo.m_pStartEnt;
|
||||
beamInfo.m_nStartAttachment = random->RandomInt( 0, NUM_ATTACHMENTS );
|
||||
beamInfo.m_nEndAttachment = random->RandomInt( 0, NUM_ATTACHMENTS );
|
||||
|
||||
// Ensure we're not the same point
|
||||
if ( beamInfo.m_nStartAttachment == beamInfo.m_nEndAttachment )
|
||||
{
|
||||
int nextStep = ( random->RandomInt( 0, 1 ) ) ? 1 : -1;
|
||||
|
||||
beamInfo.m_nEndAttachment = ( beamInfo.m_nStartAttachment + nextStep ) % NUM_ATTACHMENTS;
|
||||
}
|
||||
|
||||
beamInfo.m_nType = TE_BEAMTESLA;
|
||||
beamInfo.m_pszModelName = "sprites/lgtning.vmt";
|
||||
beamInfo.m_flHaloScale = 0.0f;
|
||||
beamInfo.m_flLife = 0.1f;
|
||||
beamInfo.m_flWidth = random->RandomFloat( 2.0f, 4.0f );
|
||||
beamInfo.m_flEndWidth = random->RandomFloat( 0.0f, 1.0f );
|
||||
beamInfo.m_flFadeLength = 0.0f;
|
||||
beamInfo.m_flAmplitude = random->RandomFloat( 16, 32 );
|
||||
beamInfo.m_flBrightness = 255.0;
|
||||
beamInfo.m_flSpeed = 0.0;
|
||||
beamInfo.m_nStartFrame = 0.0;
|
||||
beamInfo.m_flFrameRate = 1.0f;
|
||||
|
||||
if ( m_bPowerDown )
|
||||
{
|
||||
beamInfo.m_flRed = 255.0f;;
|
||||
beamInfo.m_flGreen = 64.0f;
|
||||
beamInfo.m_flBlue = 64.0f;
|
||||
}
|
||||
else if ( m_bHackedByAlyx )
|
||||
{
|
||||
beamInfo.m_flRed = 240.0f;;
|
||||
beamInfo.m_flGreen = 200.0f;
|
||||
beamInfo.m_flBlue = 80.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
beamInfo.m_flRed = 255.0f;;
|
||||
beamInfo.m_flGreen = 255.0f;
|
||||
beamInfo.m_flBlue = 255.0f;
|
||||
}
|
||||
|
||||
beamInfo.m_nSegments = 4;
|
||||
beamInfo.m_bRenderable = true;
|
||||
beamInfo.m_nFlags = 0;
|
||||
|
||||
beams->CreateBeamEntPoint( beamInfo );
|
||||
|
||||
// Draw the halo
|
||||
float color[3];
|
||||
|
||||
if ( m_bHackedByAlyx )
|
||||
{
|
||||
color[0] = 0.25f;
|
||||
color[1] = 0.05f;
|
||||
color[2] = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
color[0] = color[1] = color[2] = 0.15f;
|
||||
}
|
||||
|
||||
IMaterial *pMaterial = materials->FindMaterial( "effects/rollerglow", NULL, false );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
pRenderContext->Bind( pMaterial );
|
||||
DrawHalo( pMaterial, GetAbsOrigin(), random->RandomFloat( 6.0f*scale, 6.5f*scale ), color );
|
||||
|
||||
if ( m_bPowerDown )
|
||||
{
|
||||
color[0] = random->RandomFloat( 0.80f, 1.00f );
|
||||
color[1] = random->RandomFloat( 0.10f, 0.25f );
|
||||
color[2] = 0.0f;
|
||||
}
|
||||
else if ( m_bHackedByAlyx )
|
||||
{
|
||||
color[0] = random->RandomFloat( 0.25f, 0.75f );
|
||||
color[1] = random->RandomFloat( 0.10f, 0.25f );
|
||||
color[2] = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
color[0] = color[1] = color[2] = random->RandomFloat( 0.25f, 0.5f );
|
||||
}
|
||||
|
||||
Vector attachOrigin;
|
||||
QAngle attachAngles;
|
||||
|
||||
GetAttachment( beamInfo.m_nEndAttachment, attachOrigin, attachAngles );
|
||||
DrawHalo( pMaterial, attachOrigin, random->RandomFloat( 1.0f*scale, 1.5f*scale ), color );
|
||||
|
||||
GetAttachment( beamInfo.m_nStartAttachment, attachOrigin, attachAngles );
|
||||
DrawHalo( pMaterial, attachOrigin, random->RandomFloat( 1.0f*scale, 1.5f*scale ), color );
|
||||
}
|
||||
}
|
||||
|
||||
return BaseClass::DrawModel( flags );
|
||||
}
|
||||
279
game/client/hl2/c_plasma_beam_node.cpp
Normal file
279
game/client/hl2/c_plasma_beam_node.cpp
Normal file
@@ -0,0 +1,279 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "particles_simple.h"
|
||||
#include "c_tracer.h"
|
||||
#include "particle_collision.h"
|
||||
#include "view.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define PLASMASPARK_LIFETIME 0.5
|
||||
#define SPRAYS_PER_THINK 12
|
||||
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectPlasmaBeam )
|
||||
CLIENTEFFECT_MATERIAL( "sprites/plasmaember" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
class C_PlasmaBeamNode;
|
||||
|
||||
//##################################################################
|
||||
//
|
||||
// > CPlasmaSpray
|
||||
//
|
||||
//##################################################################
|
||||
class CPlasmaSpray : public CSimpleEmitter
|
||||
{
|
||||
public:
|
||||
CPlasmaSpray( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
|
||||
|
||||
static CSmartPtr<CPlasmaSpray> Create( const char *pDebugName );
|
||||
void Think( void );
|
||||
void UpdateVelocity( SimpleParticle *pParticle, float timeDelta );
|
||||
virtual void RenderParticles( CParticleRenderIterator *pIterator );
|
||||
virtual void SimulateParticles( CParticleSimulateIterator *pIterator );
|
||||
EHANDLE m_pOwner;
|
||||
CParticleCollision m_ParticleCollision;
|
||||
|
||||
private:
|
||||
CPlasmaSpray( const CPlasmaSpray & );
|
||||
};
|
||||
|
||||
//##################################################################
|
||||
//
|
||||
// PlasmaBeamNode - generates plasma spray
|
||||
//
|
||||
//##################################################################
|
||||
class C_PlasmaBeamNode : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_PlasmaBeamNode, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_PlasmaBeamNode();
|
||||
~C_PlasmaBeamNode(void);
|
||||
|
||||
public:
|
||||
void ClientThink(void);
|
||||
void AddEntity( void );
|
||||
void OnDataChanged(DataUpdateType_t updateType);
|
||||
bool ShouldDraw();
|
||||
bool m_bSprayOn;
|
||||
CSmartPtr<CPlasmaSpray> m_pFirePlasmaSpray;
|
||||
};
|
||||
|
||||
//##################################################################
|
||||
//
|
||||
// > CPlasmaSpray
|
||||
//
|
||||
//##################################################################
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pParticle -
|
||||
// timeDelta -
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
CSmartPtr<CPlasmaSpray> CPlasmaSpray::Create( const char *pDebugName )
|
||||
{
|
||||
CPlasmaSpray *pRet = new CPlasmaSpray( pDebugName );
|
||||
return pRet;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : fTimeDelta -
|
||||
// Output : Vector
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPlasmaSpray::UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
|
||||
{
|
||||
Vector vGravity = Vector(0,0,-1000);
|
||||
float flFrametime = gpGlobals->frametime;
|
||||
vGravity = flFrametime * vGravity;
|
||||
pParticle->m_vecVelocity += vGravity;
|
||||
}
|
||||
|
||||
|
||||
void CPlasmaSpray::SimulateParticles( CParticleSimulateIterator *pIterator )
|
||||
{
|
||||
float timeDelta = pIterator->GetTimeDelta();
|
||||
|
||||
SimpleParticle *pParticle = (SimpleParticle*)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
//Should this particle die?
|
||||
pParticle->m_flLifetime += timeDelta;
|
||||
|
||||
C_PlasmaBeamNode* pNode = (C_PlasmaBeamNode*)((C_BaseEntity*)m_pOwner);
|
||||
if ( pParticle->m_flLifetime >= pParticle->m_flDieTime )
|
||||
{
|
||||
pIterator->RemoveParticle( pParticle );
|
||||
}
|
||||
// If owner is gone or spray off remove me
|
||||
else if (pNode == NULL || !pNode->m_bSprayOn)
|
||||
{
|
||||
pIterator->RemoveParticle( pParticle );
|
||||
}
|
||||
|
||||
//Simulate the movement with collision
|
||||
trace_t trace;
|
||||
m_ParticleCollision.MoveParticle( pParticle->m_Pos, pParticle->m_vecVelocity, NULL, timeDelta, &trace );
|
||||
|
||||
pParticle = (SimpleParticle*)pIterator->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CPlasmaSpray::RenderParticles( CParticleRenderIterator *pIterator )
|
||||
{
|
||||
const SimpleParticle *pParticle = (const SimpleParticle *)pIterator->GetFirst();
|
||||
while ( pParticle )
|
||||
{
|
||||
float scale = random->RandomFloat( 0.02, 0.08 );
|
||||
|
||||
// NOTE: We need to do everything in screen space
|
||||
Vector delta;
|
||||
Vector start;
|
||||
TransformParticle(ParticleMgr()->GetModelView(), pParticle->m_Pos, start);
|
||||
float sortKey = start.z;
|
||||
|
||||
Vector3DMultiply( CurrentWorldToViewMatrix(), pParticle->m_vecVelocity, delta );
|
||||
|
||||
delta[0] *= scale;
|
||||
delta[1] *= scale;
|
||||
delta[2] *= scale;
|
||||
|
||||
// See c_tracer.* for this method
|
||||
Tracer_Draw( pIterator->GetParticleDraw(), start, delta, random->RandomInt( 2, 8 ), 0 );
|
||||
|
||||
pParticle = (const SimpleParticle *)pIterator->GetNext( sortKey );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//##################################################################
|
||||
//
|
||||
// PlasmaBeamNode - generates plasma spray
|
||||
//
|
||||
//##################################################################
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
C_PlasmaBeamNode::C_PlasmaBeamNode(void)
|
||||
{
|
||||
m_bSprayOn = false;
|
||||
m_pFirePlasmaSpray = CPlasmaSpray::Create( "C_PlasmaBeamNode" );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
C_PlasmaBeamNode::~C_PlasmaBeamNode(void)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PlasmaBeamNode::AddEntity( void )
|
||||
{
|
||||
m_pFirePlasmaSpray->SetSortOrigin( GetAbsOrigin() );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_PlasmaBeamNode::OnDataChanged(DataUpdateType_t updateType)
|
||||
{
|
||||
if (updateType == DATA_UPDATE_CREATED)
|
||||
{
|
||||
Vector vMoveDir = GetAbsVelocity();
|
||||
float flVel = VectorNormalize(vMoveDir);
|
||||
m_pFirePlasmaSpray->m_ParticleCollision.Setup( GetAbsOrigin(), &vMoveDir, 0.3,
|
||||
flVel-50, flVel+50, 800, 0.5 );
|
||||
SetNextClientThink(gpGlobals->curtime + 0.01);
|
||||
}
|
||||
C_BaseEntity::OnDataChanged(updateType);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
bool C_PlasmaBeamNode::ShouldDraw()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void C_PlasmaBeamNode::ClientThink(void)
|
||||
{
|
||||
if (!m_bSprayOn)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
trace_t trace;
|
||||
Vector vEndTrace = GetAbsOrigin() + (0.3*GetAbsVelocity());
|
||||
UTIL_TraceLine( GetAbsOrigin(), vEndTrace, MASK_SHOT, NULL, COLLISION_GROUP_NONE, &trace );
|
||||
if ( trace.fraction != 1.0f || trace.startsolid)
|
||||
{
|
||||
m_bSprayOn = false;
|
||||
return;
|
||||
}
|
||||
|
||||
PMaterialHandle handle = m_pFirePlasmaSpray->GetPMaterial( "sprites/plasmaember" );
|
||||
for (int i=0;i<SPRAYS_PER_THINK;i++)
|
||||
{
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
//Make a new particle
|
||||
if ( random->RandomInt( 0, 2 ) == 0 )
|
||||
{
|
||||
float ranx = random->RandomFloat( -28.0f, 28.0f );
|
||||
float rany = random->RandomFloat( -28.0f, 28.0f );
|
||||
float ranz = random->RandomFloat( -28.0f, 28.0f );
|
||||
|
||||
Vector vNewPos = GetAbsOrigin();
|
||||
Vector vAdd = Vector(GetAbsAngles().x,GetAbsAngles().y,GetAbsAngles().z)*random->RandomFloat(-60,120);
|
||||
vNewPos += vAdd;
|
||||
|
||||
sParticle = (SimpleParticle *) m_pFirePlasmaSpray->AddParticle( sizeof(SimpleParticle), handle, vNewPos );
|
||||
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
sParticle->m_flDieTime = PLASMASPARK_LIFETIME;
|
||||
|
||||
sParticle->m_vecVelocity = GetAbsVelocity();
|
||||
sParticle->m_vecVelocity.x += ranx;
|
||||
sParticle->m_vecVelocity.y += rany;
|
||||
sParticle->m_vecVelocity.z += ranz;
|
||||
m_pFirePlasmaSpray->m_pOwner = this;
|
||||
}
|
||||
}
|
||||
|
||||
SetNextClientThink(gpGlobals->curtime + 0.05);
|
||||
}
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_PlasmaBeamNode, DT_PlasmaBeamNode, CPlasmaBeamNode )
|
||||
RecvPropVector (RECVINFO(m_vecVelocity), 0, RecvProxy_LocalVelocity),
|
||||
RecvPropInt (RECVINFO(m_bSprayOn)),
|
||||
END_RECV_TABLE()
|
||||
340
game/client/hl2/c_prop_combine_ball.cpp
Normal file
340
game/client/hl2/c_prop_combine_ball.cpp
Normal file
@@ -0,0 +1,340 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_prop_combine_ball.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "model_types.h"
|
||||
#include "c_physicsprop.h"
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#include "fx_quad.h"
|
||||
#include "fx.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
#include "view.h"
|
||||
#include "view_scene.h"
|
||||
#include "beamdraw.h"
|
||||
|
||||
// Precache our effects
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectCombineBall )
|
||||
CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1b" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1_nocull" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2_nocull" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/ar2_altfire1b" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_PropCombineBall, DT_PropCombineBall, CPropCombineBall )
|
||||
RecvPropBool( RECVINFO( m_bEmit ) ),
|
||||
RecvPropFloat( RECVINFO( m_flRadius ) ),
|
||||
RecvPropBool( RECVINFO( m_bHeld ) ),
|
||||
RecvPropBool( RECVINFO( m_bLaunched ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PropCombineBall::C_PropCombineBall( void )
|
||||
{
|
||||
m_pFlickerMaterial = NULL;
|
||||
m_pBodyMaterial = NULL;
|
||||
m_pBlurMaterial = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCombineBall::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_vecLastOrigin = GetAbsOrigin();
|
||||
InitMaterials();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : RenderGroup_t
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderGroup_t C_PropCombineBall::GetRenderGroup( void )
|
||||
{
|
||||
return RENDER_GROUP_TRANSLUCENT_ENTITY;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Cache the material handles
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_PropCombineBall::InitMaterials( void )
|
||||
{
|
||||
// Motion blur
|
||||
if ( m_pBlurMaterial == NULL )
|
||||
{
|
||||
m_pBlurMaterial = materials->FindMaterial( "effects/ar2_altfire1b", NULL, false );
|
||||
|
||||
if ( m_pBlurMaterial == NULL )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Main body of the ball
|
||||
if ( m_pBodyMaterial == NULL )
|
||||
{
|
||||
m_pBodyMaterial = materials->FindMaterial( "effects/ar2_altfire1", NULL, false );
|
||||
|
||||
if ( m_pBodyMaterial == NULL )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Flicker material
|
||||
if ( m_pFlickerMaterial == NULL )
|
||||
{
|
||||
m_pFlickerMaterial = materials->FindMaterial( "effects/combinemuzzle1", NULL, false );
|
||||
|
||||
if ( m_pFlickerMaterial == NULL )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCombineBall::DrawMotionBlur( void )
|
||||
{
|
||||
float color[3];
|
||||
|
||||
Vector vecDir = GetAbsOrigin() - m_vecLastOrigin;
|
||||
float speed = VectorNormalize( vecDir );
|
||||
|
||||
speed = clamp( speed, 0, 32 );
|
||||
|
||||
float stepSize = MIN( ( speed * 0.5f ), 4.0f );
|
||||
|
||||
Vector spawnPos = GetAbsOrigin();
|
||||
Vector spawnStep = -vecDir * stepSize;
|
||||
|
||||
float base = RemapValClamped( speed, 4, 32, 0.0f, 1.0f );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
pRenderContext->Bind( m_pBlurMaterial );
|
||||
|
||||
// Draw the motion blurred trail
|
||||
for ( int i = 0; i < 8; i++ )
|
||||
{
|
||||
spawnPos += spawnStep;
|
||||
|
||||
color[0] = color[1] = color[2] = base * ( 1.0f - ( (float) i / 12.0f ) );
|
||||
|
||||
DrawHalo( m_pBlurMaterial, spawnPos, m_flRadius, color );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCombineBall::DrawFlicker( void )
|
||||
{
|
||||
float rand1 = random->RandomFloat( 0.2f, 0.3f );
|
||||
float rand2 = random->RandomFloat( 1.5f, 2.5f );
|
||||
|
||||
if ( gpGlobals->frametime == 0.0f )
|
||||
{
|
||||
rand1 = 0.2f;
|
||||
rand2 = 1.5f;
|
||||
}
|
||||
|
||||
float color[3];
|
||||
color[0] = color[1] = color[2] = rand1;
|
||||
|
||||
// Draw the flickering glow
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
pRenderContext->Bind( m_pFlickerMaterial );
|
||||
DrawHalo( m_pFlickerMaterial, GetAbsOrigin(), m_flRadius * rand2, color );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pMaterial -
|
||||
// source -
|
||||
// color -
|
||||
//-----------------------------------------------------------------------------
|
||||
void DrawHaloOriented( const Vector& source, float scale, float const *color, float roll )
|
||||
{
|
||||
Vector point, screen;
|
||||
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh();
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
|
||||
|
||||
// Transform source into screen space
|
||||
ScreenTransform( source, screen );
|
||||
|
||||
Vector right, up;
|
||||
float sr, cr;
|
||||
|
||||
SinCos( roll, &sr, &cr );
|
||||
|
||||
for ( int i = 0; i < 3; i++ )
|
||||
{
|
||||
right[i] = CurrentViewRight()[i] * cr + CurrentViewUp()[i] * sr;
|
||||
up[i] = CurrentViewRight()[i] * -sr + CurrentViewUp()[i] * cr;
|
||||
}
|
||||
|
||||
meshBuilder.Color3fv (color);
|
||||
meshBuilder.TexCoord2f (0, 0, 1);
|
||||
VectorMA (source, -scale, up, point);
|
||||
VectorMA (point, -scale, right, point);
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color3fv (color);
|
||||
meshBuilder.TexCoord2f (0, 0, 0);
|
||||
VectorMA (source, scale, up, point);
|
||||
VectorMA (point, -scale, right, point);
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color3fv (color);
|
||||
meshBuilder.TexCoord2f (0, 1, 0);
|
||||
VectorMA (source, scale, up, point);
|
||||
VectorMA (point, scale, right, point);
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color3fv (color);
|
||||
meshBuilder.TexCoord2f (0, 1, 1);
|
||||
VectorMA (source, -scale, up, point);
|
||||
VectorMA (point, scale, right, point);
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_PropCombineBall::DrawModel( int flags )
|
||||
{
|
||||
if ( !m_bEmit )
|
||||
return 0;
|
||||
|
||||
// Make sure our materials are cached
|
||||
if ( !InitMaterials() )
|
||||
{
|
||||
//NOTENOTE: This means that a material was not found for the combine ball, so it may not render!
|
||||
AssertOnce( 0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Draw the flickering overlay
|
||||
DrawFlicker();
|
||||
|
||||
// Draw the motion blur from movement
|
||||
if ( m_bHeld || m_bLaunched )
|
||||
{
|
||||
DrawMotionBlur();
|
||||
}
|
||||
|
||||
// Draw the model if we're being held
|
||||
if ( m_bHeld )
|
||||
{
|
||||
QAngle angles;
|
||||
VectorAngles( -CurrentViewForward(), angles );
|
||||
|
||||
// Always orient towards the camera!
|
||||
SetAbsAngles( angles );
|
||||
|
||||
BaseClass::DrawModel( flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
float color[3];
|
||||
color[0] = color[1] = color[2] = 1.0f;
|
||||
|
||||
float sinOffs = 1.0f * sin( gpGlobals->curtime * 25 );
|
||||
|
||||
float roll = SpawnTime();
|
||||
|
||||
// Draw the main ball body
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
pRenderContext->Bind( m_pBodyMaterial, (C_BaseEntity*) this );
|
||||
DrawHaloOriented( GetAbsOrigin(), m_flRadius + sinOffs, color, roll );
|
||||
}
|
||||
|
||||
m_vecLastOrigin = GetAbsOrigin();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CombineBallImpactCallback( const CEffectData &data )
|
||||
{
|
||||
// Quick flash
|
||||
FX_AddQuad( data.m_vOrigin,
|
||||
data.m_vNormal,
|
||||
data.m_flRadius * 10.0f,
|
||||
0,
|
||||
0.75f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
0.4f,
|
||||
random->RandomInt( 0, 360 ),
|
||||
0,
|
||||
Vector( 1.0f, 1.0f, 1.0f ),
|
||||
0.25f,
|
||||
"effects/combinemuzzle1_nocull",
|
||||
(FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
|
||||
|
||||
// Lingering burn
|
||||
FX_AddQuad( data.m_vOrigin,
|
||||
data.m_vNormal,
|
||||
data.m_flRadius * 2.0f,
|
||||
data.m_flRadius * 4.0f,
|
||||
0.75f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
0.4f,
|
||||
random->RandomInt( 0, 360 ),
|
||||
0,
|
||||
Vector( 1.0f, 1.0f, 1.0f ),
|
||||
0.5f,
|
||||
"effects/combinemuzzle2_nocull",
|
||||
(FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
|
||||
|
||||
// Throw sparks
|
||||
FX_ElectricSpark( data.m_vOrigin, 2, 1, &data.m_vNormal );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "cball_bounce", CombineBallImpactCallback );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CombineBallExplosionCallback( const CEffectData &data )
|
||||
{
|
||||
Vector normal(0,0,1);
|
||||
|
||||
// Throw sparks
|
||||
FX_ElectricSpark( data.m_vOrigin, 4, 1, &normal );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "cball_explode", CombineBallExplosionCallback );
|
||||
45
game/client/hl2/c_prop_combine_ball.h
Normal file
45
game/client/hl2/c_prop_combine_ball.h
Normal file
@@ -0,0 +1,45 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef CPROPCOMBINEBALL_H_
|
||||
#define CPROPCOMBINEBALL_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class C_PropCombineBall : public C_BaseAnimating
|
||||
{
|
||||
DECLARE_CLASS( C_PropCombineBall, C_BaseAnimating );
|
||||
DECLARE_CLIENTCLASS();
|
||||
public:
|
||||
|
||||
C_PropCombineBall( void );
|
||||
|
||||
virtual RenderGroup_t GetRenderGroup( void );
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
protected:
|
||||
|
||||
void DrawMotionBlur( void );
|
||||
void DrawFlicker( void );
|
||||
virtual bool InitMaterials( void );
|
||||
|
||||
Vector m_vecLastOrigin;
|
||||
bool m_bEmit;
|
||||
float m_flRadius;
|
||||
bool m_bHeld;
|
||||
bool m_bLaunched;
|
||||
|
||||
IMaterial *m_pFlickerMaterial;
|
||||
IMaterial *m_pBodyMaterial;
|
||||
IMaterial *m_pBlurMaterial;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
306
game/client/hl2/c_rotorwash.cpp
Normal file
306
game/client/hl2/c_rotorwash.cpp
Normal file
@@ -0,0 +1,306 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "particlemgr.h"
|
||||
#include "particle_prototype.h"
|
||||
#include "particle_util.h"
|
||||
#include "c_te_particlesystem.h"
|
||||
#include "fx.h"
|
||||
#include "fx_quad.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// ==============================================
|
||||
// Rotorwash particle emitter
|
||||
// ==============================================
|
||||
|
||||
#ifndef _XBOX
|
||||
|
||||
class WashEmitter : public CSimpleEmitter
|
||||
{
|
||||
public:
|
||||
|
||||
WashEmitter( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
|
||||
|
||||
static WashEmitter *Create( const char *pDebugName )
|
||||
{
|
||||
return new WashEmitter( pDebugName );
|
||||
}
|
||||
|
||||
void UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
|
||||
{
|
||||
// Float up when lifetime is half gone.
|
||||
pParticle->m_vecVelocity[ 2 ] += 64 * timeDelta;
|
||||
|
||||
// FIXME: optimize this....
|
||||
pParticle->m_vecVelocity *= ExponentialDecay( 0.8, 0.05, timeDelta );
|
||||
}
|
||||
|
||||
virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta )
|
||||
{
|
||||
pParticle->m_flRoll += pParticle->m_flRollDelta * timeDelta;
|
||||
|
||||
pParticle->m_flRollDelta += pParticle->m_flRollDelta * ( timeDelta * -2.0f );
|
||||
|
||||
//Cap the minimum roll
|
||||
if ( fabs( pParticle->m_flRollDelta ) < 0.5f )
|
||||
{
|
||||
pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.5f : -0.5f;
|
||||
}
|
||||
|
||||
return pParticle->m_flRoll;
|
||||
}
|
||||
|
||||
virtual float UpdateAlpha( const SimpleParticle *pParticle )
|
||||
{
|
||||
return ( ((float)pParticle->m_uchStartAlpha/255.0f) * sin( M_PI * (pParticle->m_flLifetime / pParticle->m_flDieTime) ) );
|
||||
}
|
||||
|
||||
private:
|
||||
WashEmitter( const WashEmitter & );
|
||||
};
|
||||
|
||||
#endif // !_XBOX
|
||||
|
||||
// ==============================================
|
||||
// Rotorwash entity
|
||||
// ==============================================
|
||||
|
||||
#define ROTORWASH_THINK_INTERVAL 0.1f
|
||||
|
||||
class C_RotorWashEmitter : public C_BaseEntity
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLASS( C_RotorWashEmitter, C_BaseEntity );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_RotorWashEmitter( void );
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
protected:
|
||||
|
||||
float m_flAltitude;
|
||||
|
||||
PMaterialHandle m_hWaterMaterial[2];
|
||||
|
||||
#ifndef _XBOX
|
||||
void InitSpawner( void );
|
||||
CSmartPtr<WashEmitter> m_pSimple;
|
||||
#endif // !XBOX
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_RotorWashEmitter, DT_RotorWashEmitter, CRotorWashEmitter)
|
||||
RecvPropFloat(RECVINFO(m_flAltitude)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_RotorWashEmitter::C_RotorWashEmitter( void )
|
||||
{
|
||||
#ifndef _XBOX
|
||||
m_pSimple = NULL;
|
||||
m_hWaterMaterial[0] = NULL;
|
||||
m_hWaterMaterial[1] = NULL;
|
||||
#endif // !_XBOX
|
||||
}
|
||||
|
||||
#ifndef _XBOX
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_RotorWashEmitter::InitSpawner( void )
|
||||
{
|
||||
if ( m_pSimple.IsValid() )
|
||||
return;
|
||||
|
||||
m_pSimple = WashEmitter::Create( "wash" );
|
||||
m_pSimple->SetNearClip( 128, 256 );
|
||||
}
|
||||
#endif // !XBOX
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_RotorWashEmitter::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( gpGlobals->curtime + ROTORWASH_THINK_INTERVAL );
|
||||
|
||||
#ifndef _XBOX
|
||||
InitSpawner();
|
||||
#endif // !XBOX
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_RotorWashEmitter::ClientThink( void )
|
||||
{
|
||||
SetNextClientThink( gpGlobals->curtime + ROTORWASH_THINK_INTERVAL );
|
||||
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin()+(Vector(0, 0, -1024)), (MASK_SOLID_BRUSHONLY|CONTENTS_WATER|CONTENTS_SLIME), NULL, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
if ( /*!m_bIgnoreSolid && */(tr.fraction == 1.0f || tr.startsolid || tr.allsolid) )
|
||||
return;
|
||||
|
||||
// If we hit the skybox, don't do it either
|
||||
if ( tr.surface.flags & SURF_SKY )
|
||||
return;
|
||||
|
||||
float heightScale = RemapValClamped( tr.fraction * 1024, 512, 1024, 1.0f, 0.0f );
|
||||
|
||||
Vector vecDustColor;
|
||||
|
||||
if ( tr.contents & CONTENTS_WATER )
|
||||
{
|
||||
vecDustColor.x = 0.8f;
|
||||
vecDustColor.y = 0.8f;
|
||||
vecDustColor.z = 0.75f;
|
||||
}
|
||||
else if ( tr.contents & CONTENTS_SLIME )
|
||||
{
|
||||
vecDustColor.x = 0.6f;
|
||||
vecDustColor.y = 0.5f;
|
||||
vecDustColor.z = 0.15f;
|
||||
}
|
||||
else
|
||||
{
|
||||
vecDustColor.x = 0.35f;
|
||||
vecDustColor.y = 0.3f;
|
||||
vecDustColor.z = 0.25f;
|
||||
}
|
||||
|
||||
#ifndef _XBOX
|
||||
|
||||
InitSpawner();
|
||||
|
||||
if ( m_pSimple.IsValid() == false )
|
||||
return;
|
||||
|
||||
m_pSimple->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
PMaterialHandle *hMaterial;
|
||||
|
||||
// Cache and set our material based on the surface we're over (ie. water)
|
||||
if ( tr.contents & (CONTENTS_WATER|CONTENTS_SLIME) )
|
||||
{
|
||||
if ( m_hWaterMaterial[0] == NULL )
|
||||
{
|
||||
m_hWaterMaterial[0] = m_pSimple->GetPMaterial("effects/splash1");
|
||||
m_hWaterMaterial[1] = m_pSimple->GetPMaterial("effects/splash2");
|
||||
}
|
||||
hMaterial = m_hWaterMaterial;
|
||||
}
|
||||
else
|
||||
{
|
||||
hMaterial = g_Mat_DustPuff;
|
||||
}
|
||||
|
||||
#endif // !XBOX
|
||||
|
||||
// If we're above water, make ripples
|
||||
if ( tr.contents & (CONTENTS_WATER|CONTENTS_SLIME) )
|
||||
{
|
||||
float flScale = random->RandomFloat( 7.5f, 8.5f );
|
||||
|
||||
Vector color = Vector( 0.8f, 0.8f, 0.75f );
|
||||
Vector startPos = tr.endpos + Vector(0,0,8);
|
||||
Vector endPos = tr.endpos + Vector(0,0,-64);
|
||||
|
||||
if ( tr.fraction < 1.0f )
|
||||
{
|
||||
//Add a ripple quad to the surface
|
||||
FX_AddQuad( tr.endpos + ( tr.plane.normal * 0.5f ),
|
||||
tr.plane.normal,
|
||||
64.0f * flScale,
|
||||
128.0f * flScale,
|
||||
0.8f,
|
||||
0.75f * heightScale,
|
||||
0.0f,
|
||||
0.75f,
|
||||
random->RandomFloat( 0, 360 ),
|
||||
random->RandomFloat( -2.0f, 2.0f ),
|
||||
vecDustColor,
|
||||
0.2f,
|
||||
"effects/splashwake3",
|
||||
(FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _XBOX
|
||||
int numRingSprites = 32;
|
||||
float yaw = random->RandomFloat( 0, 2*M_PI ); // Randomly placed on the unit circle
|
||||
float yawIncr = (2*M_PI) / numRingSprites;
|
||||
Vector vecForward;
|
||||
Vector offset;
|
||||
SimpleParticle *pParticle;
|
||||
|
||||
// Draw the rings
|
||||
for ( int i = 0; i < numRingSprites; i++ )
|
||||
{
|
||||
// Get our x,y on the unit circle
|
||||
SinCos( yaw, &vecForward.y, &vecForward.x );
|
||||
|
||||
// Increment ahead
|
||||
yaw += yawIncr;
|
||||
|
||||
// @NOTE toml (3-28-07): broke out following expression because vc2005 optimizer was screwing up in presence of SinCos inline assembly. Would also
|
||||
// go away if offset were referenced below as in the AddLineOverlay()
|
||||
//offset = ( RandomVector( -4.0f, 4.0f ) + tr.endpos ) + ( vecForward * 128.0f );
|
||||
|
||||
offset = vecForward * 128.0f;
|
||||
offset += tr.endpos + RandomVector( -4.0f, 4.0f );
|
||||
|
||||
|
||||
pParticle = (SimpleParticle *) m_pSimple->AddParticle( sizeof(SimpleParticle), hMaterial[random->RandomInt(0,1)], offset );
|
||||
|
||||
if ( pParticle != NULL )
|
||||
{
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat( 0.25f, 1.0f );
|
||||
|
||||
pParticle->m_vecVelocity = vecForward * random->RandomFloat( 1000, 1500 );
|
||||
|
||||
#if __EXPLOSION_DEBUG
|
||||
debugoverlay->AddLineOverlay( m_vecOrigin, m_vecOrigin + pParticle->m_vecVelocity, 255, 0, 0, false, 3 );
|
||||
#endif
|
||||
|
||||
if ( tr.contents & CONTENTS_SLIME )
|
||||
{
|
||||
vecDustColor.x = random->RandomFloat( 0.4f, 0.6f );
|
||||
vecDustColor.y = random->RandomFloat( 0.3f, 0.5f );
|
||||
vecDustColor.z = random->RandomFloat( 0.1f, 0.2f );
|
||||
}
|
||||
|
||||
pParticle->m_uchColor[0] = vecDustColor.x * 255.0f;
|
||||
pParticle->m_uchColor[1] = vecDustColor.y * 255.0f;
|
||||
pParticle->m_uchColor[2] = vecDustColor.z * 255.0f;
|
||||
|
||||
pParticle->m_uchStartSize = random->RandomInt( 16, 64 );
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize * 4;
|
||||
|
||||
pParticle->m_uchStartAlpha = random->RandomFloat( 16, 32 ) * heightScale;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -16.0f, 16.0f );
|
||||
}
|
||||
}
|
||||
#endif // !XBOX
|
||||
}
|
||||
327
game/client/hl2/c_script_intro.cpp
Normal file
327
game/client/hl2/c_script_intro.cpp
Normal file
@@ -0,0 +1,327 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "shareddefs.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "view.h"
|
||||
#include "iviewrender.h"
|
||||
#include "view_shared.h"
|
||||
#include "viewrender.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern IntroData_t *g_pIntroData;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_ScriptIntro : public C_BaseEntity
|
||||
{
|
||||
DECLARE_CLASS( C_ScriptIntro, C_BaseEntity );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_ScriptIntro( void );
|
||||
~C_ScriptIntro( void );
|
||||
void PostDataUpdate( DataUpdateType_t updateType );
|
||||
void ClientThink( void );
|
||||
void CalculateFOV( void );
|
||||
void CalculateAlpha( void );
|
||||
|
||||
public:
|
||||
int m_iNextFOV;
|
||||
int m_iFOV;
|
||||
int m_iPrevFOV;
|
||||
int m_iStartFOV;
|
||||
float m_flNextFOVBlendTime;
|
||||
float m_flFOVBlendStartTime;
|
||||
bool m_bAlternateFOV;
|
||||
|
||||
// Our intro data block
|
||||
IntroData_t m_IntroData;
|
||||
|
||||
private:
|
||||
Vector m_vecCameraView;
|
||||
QAngle m_vecCameraViewAngles;
|
||||
int m_iBlendMode;
|
||||
int m_iNextBlendMode;
|
||||
float m_flNextBlendTime;
|
||||
float m_flBlendStartTime;
|
||||
bool m_bActive;
|
||||
EHANDLE m_hCameraEntity;
|
||||
|
||||
// Fades
|
||||
float m_flFadeColor[3]; // Server's desired fade color
|
||||
float m_flFadeAlpha; // Server's desired fade alpha
|
||||
float m_flPrevServerFadeAlpha; // Previous server's desired fade alpha
|
||||
float m_flFadeDuration; // Time it should take to reach the server's new fade alpha
|
||||
float m_flFadeTimeStartedAt; // Time at which we last recieved a new desired fade alpha
|
||||
float m_flFadeAlphaStartedAt; // Alpha at which we last received a new desired fade alpha
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_ScriptIntro, DT_ScriptIntro, CScriptIntro )
|
||||
RecvPropVector( RECVINFO( m_vecCameraView ) ),
|
||||
RecvPropVector( RECVINFO( m_vecCameraViewAngles ) ),
|
||||
RecvPropInt( RECVINFO( m_iBlendMode ) ),
|
||||
RecvPropInt( RECVINFO( m_iNextBlendMode ) ),
|
||||
RecvPropFloat( RECVINFO( m_flNextBlendTime ) ),
|
||||
RecvPropFloat( RECVINFO( m_flBlendStartTime ) ),
|
||||
RecvPropBool( RECVINFO( m_bActive ) ),
|
||||
|
||||
// Fov & fov blends
|
||||
RecvPropInt( RECVINFO( m_iFOV ) ),
|
||||
RecvPropInt( RECVINFO( m_iNextFOV ) ),
|
||||
RecvPropInt( RECVINFO( m_iStartFOV ) ),
|
||||
RecvPropFloat( RECVINFO( m_flNextFOVBlendTime ) ),
|
||||
RecvPropFloat( RECVINFO( m_flFOVBlendStartTime ) ),
|
||||
RecvPropBool( RECVINFO( m_bAlternateFOV ) ),
|
||||
|
||||
// Fades
|
||||
RecvPropFloat( RECVINFO( m_flFadeAlpha ) ),
|
||||
RecvPropArray( RecvPropFloat( RECVINFO( m_flFadeColor[0] ) ), m_flFadeColor ),
|
||||
RecvPropFloat( RECVINFO( m_flFadeDuration ) ),
|
||||
RecvPropEHandle(RECVINFO(m_hCameraEntity)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ScriptIntro::C_ScriptIntro( void )
|
||||
{
|
||||
m_bActive = false;
|
||||
m_vecCameraView = vec3_origin;
|
||||
m_vecCameraViewAngles = vec3_angle;
|
||||
m_iBlendMode = 0;
|
||||
m_iNextBlendMode = 0;
|
||||
m_flNextBlendTime = 0;
|
||||
m_flBlendStartTime = 0;
|
||||
m_IntroData.m_playerViewFOV = 0;
|
||||
m_flFadeAlpha = 0;
|
||||
m_flPrevServerFadeAlpha = 0;
|
||||
m_flFadeDuration = 0;
|
||||
m_flFadeTimeStartedAt = 0;
|
||||
m_flFadeAlphaStartedAt = 0;
|
||||
m_hCameraEntity = NULL;
|
||||
m_iPrevFOV = 0;
|
||||
m_iStartFOV = 0;
|
||||
|
||||
g_pIntroData = NULL;
|
||||
|
||||
// Setup fade colors
|
||||
m_IntroData.m_flCurrentFadeColor[0] = m_flFadeColor[0];
|
||||
m_IntroData.m_flCurrentFadeColor[1] = m_flFadeColor[1];
|
||||
m_IntroData.m_flCurrentFadeColor[2] = m_flFadeColor[2];
|
||||
m_IntroData.m_flCurrentFadeColor[3] = m_flFadeAlpha;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_ScriptIntro::~C_ScriptIntro( void )
|
||||
{
|
||||
g_pIntroData = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ScriptIntro::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PostDataUpdate( updateType );
|
||||
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
|
||||
// Fill out the intro data
|
||||
m_IntroData.m_vecCameraView = m_vecCameraView;
|
||||
m_IntroData.m_vecCameraViewAngles = m_vecCameraViewAngles;
|
||||
m_IntroData.m_Passes.SetCount( 0 );
|
||||
|
||||
// Find/Create our first pass
|
||||
IntroDataBlendPass_t *pass1;
|
||||
if ( m_IntroData.m_Passes.Count() == 0 )
|
||||
{
|
||||
pass1 = &m_IntroData.m_Passes[m_IntroData.m_Passes.AddToTail()];
|
||||
}
|
||||
else
|
||||
{
|
||||
pass1 = &m_IntroData.m_Passes[0];
|
||||
}
|
||||
Assert(pass1);
|
||||
pass1->m_BlendMode = m_iBlendMode;
|
||||
pass1->m_Alpha = 1.0f;
|
||||
|
||||
if ( m_vecCameraView == vec3_origin )
|
||||
{
|
||||
m_IntroData.m_bDrawPrimary = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_IntroData.m_bDrawPrimary = true;
|
||||
}
|
||||
|
||||
// If we're currently blending to a new mode, set the second pass
|
||||
if ( m_flNextBlendTime > gpGlobals->curtime )
|
||||
{
|
||||
IntroDataBlendPass_t *pass2;
|
||||
if ( m_IntroData.m_Passes.Count() < 2 )
|
||||
{
|
||||
pass2 = &m_IntroData.m_Passes[m_IntroData.m_Passes.AddToTail()];
|
||||
|
||||
//Msg("STARTED BLEND: Mode %d to %d.\n", m_IntroData.m_Passes[0].m_BlendMode, m_iNextBlendMode );
|
||||
}
|
||||
else
|
||||
{
|
||||
pass2 = &m_IntroData.m_Passes[1];
|
||||
|
||||
Assert( pass2->m_BlendMode == m_iNextBlendMode );
|
||||
}
|
||||
Assert(pass2);
|
||||
pass2->m_BlendMode = m_iNextBlendMode;
|
||||
pass2->m_Alpha = 0.0f;
|
||||
}
|
||||
else if ( m_IntroData.m_Passes.Count() == 2 )
|
||||
{
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
//Msg("FINISHED BLEND.\n");
|
||||
m_IntroData.m_Passes.Remove(1);
|
||||
}
|
||||
|
||||
// Set the introdata our data chunk
|
||||
if ( m_bActive )
|
||||
{
|
||||
g_pIntroData = &m_IntroData;
|
||||
}
|
||||
else if ( g_pIntroData == &m_IntroData )
|
||||
{
|
||||
g_pIntroData = NULL;
|
||||
}
|
||||
|
||||
// Update the fade color
|
||||
m_IntroData.m_flCurrentFadeColor[0] = m_flFadeColor[0];
|
||||
m_IntroData.m_flCurrentFadeColor[1] = m_flFadeColor[1];
|
||||
m_IntroData.m_flCurrentFadeColor[2] = m_flFadeColor[2];
|
||||
|
||||
// Started fading?
|
||||
if ( m_flFadeAlpha != m_flPrevServerFadeAlpha )
|
||||
{
|
||||
m_flFadeTimeStartedAt = gpGlobals->curtime;
|
||||
m_flFadeAlphaStartedAt = m_IntroData.m_flCurrentFadeColor[3];
|
||||
m_flPrevServerFadeAlpha = m_flFadeAlpha;
|
||||
|
||||
if ( !m_flFadeDuration )
|
||||
{
|
||||
m_flFadeDuration = 0.01;
|
||||
}
|
||||
|
||||
//Msg("STARTING NEW FADE: alpha %.2f, duration %.2f.\n", m_flFadeAlpha, m_flFadeDuration );
|
||||
}
|
||||
|
||||
if ( m_iPrevFOV != m_iFOV )
|
||||
{
|
||||
m_IntroData.m_playerViewFOV = m_iFOV;
|
||||
m_iPrevFOV = m_iFOV;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ScriptIntro::ClientThink( void )
|
||||
{
|
||||
Assert( m_IntroData.m_Passes.Count() <= 2 );
|
||||
|
||||
if ( m_hCameraEntity )
|
||||
{
|
||||
m_IntroData.m_vecCameraView = m_hCameraEntity->GetAbsOrigin();
|
||||
m_IntroData.m_vecCameraViewAngles = m_hCameraEntity->GetAbsAngles();
|
||||
}
|
||||
|
||||
CalculateFOV();
|
||||
CalculateAlpha();
|
||||
|
||||
// Calculate the blend levels of each pass
|
||||
float flPerc = 1.0;
|
||||
if ( (m_flNextBlendTime - m_flBlendStartTime) != 0 )
|
||||
{
|
||||
flPerc = clamp( (gpGlobals->curtime - m_flBlendStartTime) / (m_flNextBlendTime - m_flBlendStartTime), 0, 1 );
|
||||
}
|
||||
|
||||
// Detect when we're finished blending
|
||||
if ( flPerc >= 1.0 )
|
||||
{
|
||||
if ( m_IntroData.m_Passes.Count() == 2 )
|
||||
{
|
||||
// We're done blending
|
||||
m_IntroData.m_Passes[0].m_BlendMode = m_IntroData.m_Passes[1].m_BlendMode;
|
||||
m_IntroData.m_Passes[0].m_Alpha = 1.0;
|
||||
m_IntroData.m_Passes.Remove(1);
|
||||
|
||||
//Msg("FINISHED BLEND.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_IntroData.m_Passes[0].m_Alpha = 1.0f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
if ( m_flNextBlendTime >= gpGlobals->curtime )
|
||||
{
|
||||
Msg("INTRO BLENDING: Blending from mode %d to %d.\n", m_IntroData.m_Passes[0].m_BlendMode, m_IntroData.m_Passes[1].m_BlendMode );
|
||||
Msg(" curtime %.2f StartedAt %.2f FinishAt: %.2f\n", gpGlobals->curtime, m_flBlendStartTime, m_flNextBlendTime );
|
||||
Msg(" Perc: %.2f\n", flPerc );
|
||||
}
|
||||
*/
|
||||
|
||||
if ( m_IntroData.m_Passes.Count() == 2 )
|
||||
{
|
||||
m_IntroData.m_Passes[0].m_Alpha = 1.0 - flPerc;
|
||||
m_IntroData.m_Passes[1].m_Alpha = flPerc;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_IntroData.m_Passes[0].m_Alpha = 1.0 - flPerc;
|
||||
}
|
||||
}
|
||||
|
||||
extern float ScriptInfo_CalculateFOV( float flFOVBlendStartTime, float flNextFOVBlendTime, int nFOV, int nNextFOV, bool bSplineRamp );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ScriptIntro::CalculateFOV( void )
|
||||
{
|
||||
// We're past our blending time so we're at our target
|
||||
if ( m_flNextFOVBlendTime >= gpGlobals->curtime )
|
||||
{
|
||||
// Calculate where we're at
|
||||
m_IntroData.m_playerViewFOV = ScriptInfo_CalculateFOV( m_flFOVBlendStartTime, m_flNextFOVBlendTime, m_iStartFOV, m_iNextFOV, m_bAlternateFOV );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_ScriptIntro::CalculateAlpha( void )
|
||||
{
|
||||
// Fill out the fade alpha
|
||||
float flNewAlpha = RemapValClamped( gpGlobals->curtime, m_flFadeTimeStartedAt, m_flFadeTimeStartedAt + m_flFadeDuration, m_flFadeAlphaStartedAt, m_flFadeAlpha );
|
||||
/*
|
||||
if ( m_IntroData.m_flCurrentFadeColor[3] != flNewAlpha )
|
||||
{
|
||||
Msg("INTRO FADING: curtime %.2f StartedAt %.2f Duration: %.2f\n", gpGlobals->curtime, m_flFadeTimeStartedAt, m_flFadeDuration );
|
||||
Msg(" TimePassed %.2f Alpha: %.2f\n", RemapValClamped( gpGlobals->curtime, m_flFadeTimeStartedAt, m_flFadeTimeStartedAt + m_flFadeDuration, 0.0, 1.0 ), m_IntroData.m_flCurrentFadeColor[3] );
|
||||
}
|
||||
*/
|
||||
|
||||
m_IntroData.m_flCurrentFadeColor[3] = flNewAlpha;
|
||||
}
|
||||
|
||||
1048
game/client/hl2/c_strider.cpp
Normal file
1048
game/client/hl2/c_strider.cpp
Normal file
File diff suppressed because it is too large
Load Diff
110
game/client/hl2/c_te_concussiveexplosion.cpp
Normal file
110
game/client/hl2/c_te_concussiveexplosion.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_te_particlesystem.h"
|
||||
#include "fx.h"
|
||||
#include "ragdollexplosionenumerator.h"
|
||||
#include "tier1/KeyValues.h"
|
||||
#include "toolframework_client.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Concussive explosion entity
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_TEConcussiveExplosion : public C_TEParticleSystem
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_TEConcussiveExplosion, C_TEParticleSystem );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
virtual void PostDataUpdate( DataUpdateType_t updateType );
|
||||
|
||||
void AffectRagdolls( void );
|
||||
|
||||
Vector m_vecNormal;
|
||||
float m_flScale;
|
||||
int m_nRadius;
|
||||
int m_nMagnitude;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Networking
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TEConcussiveExplosion, DT_TEConcussiveExplosion, CTEConcussiveExplosion )
|
||||
RecvPropVector( RECVINFO(m_vecNormal)),
|
||||
RecvPropFloat( RECVINFO(m_flScale)),
|
||||
RecvPropInt( RECVINFO(m_nRadius)),
|
||||
RecvPropInt( RECVINFO(m_nMagnitude)),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TEConcussiveExplosion::AffectRagdolls( void )
|
||||
{
|
||||
if ( ( m_nRadius == 0 ) || ( m_nMagnitude == 0 ) )
|
||||
return;
|
||||
|
||||
CRagdollExplosionEnumerator ragdollEnum( m_vecOrigin, m_nRadius, m_nMagnitude );
|
||||
partition->EnumerateElementsInSphere( PARTITION_CLIENT_RESPONSIVE_EDICTS, m_vecOrigin, m_nRadius, false, &ragdollEnum );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Recording
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline void RecordConcussiveExplosion( const Vector& start, const Vector &vecDirection )
|
||||
{
|
||||
if ( !ToolsEnabled() )
|
||||
return;
|
||||
|
||||
if ( clienttools->IsInRecordingMode() )
|
||||
{
|
||||
KeyValues *msg = new KeyValues( "TempEntity" );
|
||||
|
||||
msg->SetInt( "te", TE_CONCUSSIVE_EXPLOSION );
|
||||
msg->SetString( "name", "TE_ConcussiveExplosion" );
|
||||
msg->SetFloat( "time", gpGlobals->curtime );
|
||||
msg->SetFloat( "originx", start.x );
|
||||
msg->SetFloat( "originy", start.y );
|
||||
msg->SetFloat( "originz", start.z );
|
||||
msg->SetFloat( "directionx", vecDirection.x );
|
||||
msg->SetFloat( "directiony", vecDirection.y );
|
||||
msg->SetFloat( "directionz", vecDirection.z );
|
||||
|
||||
ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
|
||||
msg->deleteThis();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_TEConcussiveExplosion::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
AffectRagdolls();
|
||||
|
||||
FX_ConcussiveExplosion( m_vecOrigin, m_vecNormal );
|
||||
RecordConcussiveExplosion( m_vecOrigin, m_vecNormal );
|
||||
}
|
||||
|
||||
void TE_ConcussiveExplosion( IRecipientFilter& filter, float delay, KeyValues *pKeyValues )
|
||||
{
|
||||
Vector vecOrigin, vecDirection;
|
||||
vecOrigin.x = pKeyValues->GetFloat( "originx" );
|
||||
vecOrigin.y = pKeyValues->GetFloat( "originy" );
|
||||
vecOrigin.z = pKeyValues->GetFloat( "originz" );
|
||||
vecDirection.x = pKeyValues->GetFloat( "directionx" );
|
||||
vecDirection.y = pKeyValues->GetFloat( "directiony" );
|
||||
vecDirection.z = pKeyValues->GetFloat( "directionz" );
|
||||
FX_ConcussiveExplosion( vecOrigin, vecDirection );
|
||||
}
|
||||
414
game/client/hl2/c_te_flare.cpp
Normal file
414
game/client/hl2/c_te_flare.cpp
Normal file
@@ -0,0 +1,414 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Flare effects
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
#include "particles_simple.h"
|
||||
#include "iefx.h"
|
||||
#include "dlight.h"
|
||||
#include "view.h"
|
||||
#include "fx.h"
|
||||
#include "clientsideeffects.h"
|
||||
#include "c_pixel_visibility.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//Precahce the effects
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectFlares )
|
||||
CLIENTEFFECT_MATERIAL( "effects/redflare" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/yellowflare" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/yellowflare_noz" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
class C_Flare : public C_BaseCombatCharacter, CSimpleEmitter
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( C_Flare, C_BaseCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
|
||||
C_Flare();
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType );
|
||||
void Update( float timeDelta );
|
||||
void NotifyDestroyParticle( Particle* pParticle );
|
||||
void NotifyShouldTransmit( ShouldTransmitState_t state );
|
||||
void RestoreResources( void );
|
||||
|
||||
float m_flTimeBurnOut;
|
||||
float m_flScale;
|
||||
bool m_bLight;
|
||||
bool m_bSmoke;
|
||||
bool m_bPropFlare;
|
||||
pixelvis_handle_t m_queryHandle;
|
||||
|
||||
|
||||
private:
|
||||
C_Flare( const C_Flare & );
|
||||
TimedEvent m_teSmokeSpawn;
|
||||
|
||||
int m_iAttachment;
|
||||
|
||||
SimpleParticle *m_pParticle[2];
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_Flare, DT_Flare, CFlare )
|
||||
RecvPropFloat( RECVINFO( m_flTimeBurnOut ) ),
|
||||
RecvPropFloat( RECVINFO( m_flScale ) ),
|
||||
RecvPropInt( RECVINFO( m_bLight ) ),
|
||||
RecvPropInt( RECVINFO( m_bSmoke ) ),
|
||||
RecvPropInt( RECVINFO( m_bPropFlare ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_Flare::C_Flare() : CSimpleEmitter( "C_Flare" )
|
||||
{
|
||||
m_pParticle[0] = NULL;
|
||||
m_pParticle[1] = NULL;
|
||||
m_flTimeBurnOut = 0.0f;
|
||||
|
||||
m_bLight = true;
|
||||
m_bSmoke = true;
|
||||
m_bPropFlare = false;
|
||||
|
||||
SetDynamicallyAllocated( false );
|
||||
m_queryHandle = 0;
|
||||
|
||||
m_iAttachment = -1;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : state -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Flare::NotifyShouldTransmit( ShouldTransmitState_t state )
|
||||
{
|
||||
if ( state == SHOULDTRANSMIT_END )
|
||||
{
|
||||
AddEffects( EF_NODRAW );
|
||||
}
|
||||
else if ( state == SHOULDTRANSMIT_START )
|
||||
{
|
||||
RemoveEffects( EF_NODRAW );
|
||||
}
|
||||
|
||||
BaseClass::NotifyShouldTransmit( state );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bool -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Flare::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetSortOrigin( GetAbsOrigin() );
|
||||
if ( m_bSmoke )
|
||||
{
|
||||
m_teSmokeSpawn.Init( 8 );
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Flare::RestoreResources( void )
|
||||
{
|
||||
if ( m_pParticle[0] == NULL )
|
||||
{
|
||||
m_pParticle[0] = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), GetPMaterial( "effects/redflare" ), GetAbsOrigin() );
|
||||
|
||||
if ( m_pParticle[0] != NULL )
|
||||
{
|
||||
m_pParticle[0]->m_uchColor[0] = m_pParticle[0]->m_uchColor[1] = m_pParticle[0]->m_uchColor[2] = 0;
|
||||
m_pParticle[0]->m_flRoll = random->RandomInt( 0, 360 );
|
||||
m_pParticle[0]->m_flRollDelta = random->RandomFloat( 1.0f, 4.0f );
|
||||
m_pParticle[0]->m_flLifetime = 0.0f;
|
||||
m_pParticle[0]->m_flDieTime = 10.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_pParticle[1] == NULL )
|
||||
{
|
||||
m_pParticle[1] = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), GetPMaterial( "effects/yellowflare_noz" ), GetAbsOrigin() );
|
||||
|
||||
if ( m_pParticle[1] != NULL )
|
||||
{
|
||||
m_pParticle[1]->m_uchColor[0] = m_pParticle[1]->m_uchColor[1] = m_pParticle[1]->m_uchColor[2] = 0;
|
||||
m_pParticle[1]->m_flRoll = random->RandomInt( 0, 360 );
|
||||
m_pParticle[1]->m_flRollDelta = random->RandomFloat( 1.0f, 4.0f );
|
||||
m_pParticle[1]->m_flLifetime = 0.0f;
|
||||
m_pParticle[1]->m_flDieTime = 10.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pParticle -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Flare::NotifyDestroyParticle( Particle* pParticle )
|
||||
{
|
||||
if ( pParticle == m_pParticle[0] )
|
||||
{
|
||||
m_pParticle[0] = NULL;
|
||||
}
|
||||
|
||||
if ( pParticle == m_pParticle[1] )
|
||||
{
|
||||
m_pParticle[1] = NULL;
|
||||
}
|
||||
|
||||
CSimpleEmitter::NotifyDestroyParticle( pParticle );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : timeDelta -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_Flare::Update( float timeDelta )
|
||||
{
|
||||
if ( !IsVisible() )
|
||||
return;
|
||||
|
||||
CSimpleEmitter::Update( timeDelta );
|
||||
|
||||
//Make sure our stored resources are up to date
|
||||
RestoreResources();
|
||||
|
||||
//Don't do this if the console is down
|
||||
if ( timeDelta <= 0.0f )
|
||||
return;
|
||||
|
||||
//Check for LOS
|
||||
pixelvis_queryparams_t params;
|
||||
params.Init(GetAbsOrigin());
|
||||
params.proxySize = 8.0f; // Inches
|
||||
|
||||
float visible = PixelVisibility_FractionVisible( params, &m_queryHandle );
|
||||
|
||||
float fColor;
|
||||
#ifdef HL2_CLIENT_DLL
|
||||
float baseScale = m_flScale;
|
||||
#else
|
||||
// NOTE!!! This is bigger by a factor of 1.2 to deal with fixing a bug from HL2. See dlight_t.h
|
||||
float baseScale = m_flScale * 1.2f;
|
||||
#endif
|
||||
|
||||
//Account for fading out
|
||||
if ( ( m_flTimeBurnOut != -1.0f ) && ( ( m_flTimeBurnOut - gpGlobals->curtime ) <= 10.0f ) )
|
||||
{
|
||||
baseScale *= ( ( m_flTimeBurnOut - gpGlobals->curtime ) / 10.0f );
|
||||
}
|
||||
|
||||
bool bVisible = (baseScale < 0.01f || visible == 0.0f) ? false : true;
|
||||
//Clamp the scale if vanished
|
||||
if ( !bVisible )
|
||||
{
|
||||
if ( m_pParticle[0] != NULL )
|
||||
{
|
||||
m_pParticle[0]->m_flDieTime = gpGlobals->curtime;
|
||||
m_pParticle[0]->m_uchStartSize = m_pParticle[0]->m_uchEndSize = 0;
|
||||
m_pParticle[0]->m_uchColor[0] = 0;
|
||||
m_pParticle[0]->m_uchColor[1] = 0;
|
||||
m_pParticle[0]->m_uchColor[2] = 0;
|
||||
}
|
||||
|
||||
if ( m_pParticle[1] != NULL )
|
||||
{
|
||||
m_pParticle[1]->m_flDieTime = gpGlobals->curtime;
|
||||
m_pParticle[1]->m_uchStartSize = m_pParticle[1]->m_uchEndSize = 0;
|
||||
m_pParticle[1]->m_uchColor[0] = 0;
|
||||
m_pParticle[1]->m_uchColor[1] = 0;
|
||||
m_pParticle[1]->m_uchColor[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( baseScale < 0.01f )
|
||||
return;
|
||||
//
|
||||
// Dynamic light
|
||||
//
|
||||
|
||||
if ( m_bLight )
|
||||
{
|
||||
dlight_t *dl= effects->CL_AllocDlight( index );
|
||||
|
||||
|
||||
|
||||
if ( m_bPropFlare == false )
|
||||
{
|
||||
dl->origin = GetAbsOrigin();
|
||||
dl->color.r = 255;
|
||||
dl->die = gpGlobals->curtime + 0.1f;
|
||||
|
||||
dl->radius = baseScale * random->RandomFloat( 110.0f, 128.0f );
|
||||
dl->color.g = dl->color.b = random->RandomInt( 32, 64 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_iAttachment == -1 )
|
||||
{
|
||||
m_iAttachment = LookupAttachment( "fuse" );
|
||||
}
|
||||
|
||||
if ( m_iAttachment != -1 )
|
||||
{
|
||||
Vector effect_origin;
|
||||
QAngle effect_angles;
|
||||
|
||||
GetAttachment( m_iAttachment, effect_origin, effect_angles );
|
||||
|
||||
//Raise the light a little bit away from the flare so it lights it up better.
|
||||
dl->origin = effect_origin + Vector( 0, 0, 4 );
|
||||
dl->color.r = 255;
|
||||
dl->die = gpGlobals->curtime + 0.1f;
|
||||
|
||||
dl->radius = baseScale * random->RandomFloat( 245.0f, 256.0f );
|
||||
dl->color.g = dl->color.b = random->RandomInt( 95, 128 );
|
||||
|
||||
dlight_t *el= effects->CL_AllocElight( index );
|
||||
|
||||
el->origin = effect_origin;
|
||||
el->color.r = 255;
|
||||
el->color.g = dl->color.b = random->RandomInt( 95, 128 );
|
||||
el->radius = baseScale * random->RandomFloat( 260.0f, 290.0f );
|
||||
el->die = gpGlobals->curtime + 0.1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Smoke
|
||||
//
|
||||
|
||||
float dt = timeDelta;
|
||||
|
||||
if ( m_bSmoke )
|
||||
{
|
||||
while ( m_teSmokeSpawn.NextEvent( dt ) )
|
||||
{
|
||||
Vector smokeOrg = GetAbsOrigin();
|
||||
|
||||
Vector flareScreenDir = ( smokeOrg - MainViewOrigin() );
|
||||
VectorNormalize( flareScreenDir );
|
||||
|
||||
smokeOrg = smokeOrg + ( flareScreenDir * 2.0f );
|
||||
smokeOrg[2] += baseScale * 4.0f;
|
||||
|
||||
SimpleParticle *sParticle = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[1], smokeOrg );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
sParticle->m_flDieTime = 1.0f;
|
||||
|
||||
sParticle->m_vecVelocity = Vector( random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( 8.0f, 16.0f ) + 32.0f );
|
||||
|
||||
if ( m_bPropFlare )
|
||||
{
|
||||
sParticle->m_uchColor[0] = 255;
|
||||
sParticle->m_uchColor[1] = 100;
|
||||
sParticle->m_uchColor[2] = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
sParticle->m_uchColor[0] = 255;
|
||||
sParticle->m_uchColor[1] = 48;
|
||||
sParticle->m_uchColor[2] = 48;
|
||||
}
|
||||
|
||||
sParticle->m_uchStartAlpha = random->RandomInt( 64, 90 );
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchStartSize = random->RandomInt( 2, 4 );
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 8.0f;
|
||||
sParticle->m_flRoll = random->RandomInt( 0, 2*M_PI );
|
||||
sParticle->m_flRollDelta = random->RandomFloat( -(M_PI/6.0f), M_PI/6.0f );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bVisible )
|
||||
return;
|
||||
|
||||
//
|
||||
// Outer glow
|
||||
//
|
||||
|
||||
Vector offset;
|
||||
|
||||
//Cause the base of the effect to shake
|
||||
offset.Random( -0.5f * baseScale, 0.5f * baseScale );
|
||||
offset += GetAbsOrigin();
|
||||
|
||||
if ( m_pParticle[0] != NULL )
|
||||
{
|
||||
m_pParticle[0]->m_Pos = offset;
|
||||
m_pParticle[0]->m_flLifetime = 0.0f;
|
||||
m_pParticle[0]->m_flDieTime = 2.0f;
|
||||
|
||||
m_pParticle[0]->m_vecVelocity.Init();
|
||||
|
||||
fColor = random->RandomInt( 100.0f, 128.0f ) * visible;
|
||||
|
||||
m_pParticle[0]->m_uchColor[0] = fColor;
|
||||
m_pParticle[0]->m_uchColor[1] = fColor;
|
||||
m_pParticle[0]->m_uchColor[2] = fColor;
|
||||
m_pParticle[0]->m_uchStartAlpha = fColor;
|
||||
m_pParticle[0]->m_uchEndAlpha = fColor;
|
||||
m_pParticle[0]->m_uchStartSize = baseScale * (float) random->RandomInt( 32, 48 );
|
||||
m_pParticle[0]->m_uchEndSize = m_pParticle[0]->m_uchStartSize;
|
||||
m_pParticle[0]->m_flRollDelta = 0.0f;
|
||||
|
||||
if ( random->RandomInt( 0, 4 ) == 3 )
|
||||
{
|
||||
m_pParticle[0]->m_flRoll += random->RandomInt( 2, 8 );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Inner core
|
||||
//
|
||||
|
||||
//Cause the base of the effect to shake
|
||||
offset.Random( -1.0f * baseScale, 1.0f * baseScale );
|
||||
offset += GetAbsOrigin();
|
||||
|
||||
if ( m_pParticle[1] != NULL )
|
||||
{
|
||||
m_pParticle[1]->m_Pos = offset;
|
||||
m_pParticle[1]->m_flLifetime = 0.0f;
|
||||
m_pParticle[1]->m_flDieTime = 2.0f;
|
||||
|
||||
m_pParticle[1]->m_vecVelocity.Init();
|
||||
|
||||
fColor = 255 * visible;
|
||||
|
||||
m_pParticle[1]->m_uchColor[0] = fColor;
|
||||
m_pParticle[1]->m_uchColor[1] = fColor;
|
||||
m_pParticle[1]->m_uchColor[2] = fColor;
|
||||
m_pParticle[1]->m_uchStartAlpha = fColor;
|
||||
m_pParticle[1]->m_uchEndAlpha = fColor;
|
||||
m_pParticle[1]->m_uchStartSize = baseScale * (float) random->RandomInt( 2, 4 );
|
||||
m_pParticle[1]->m_uchEndSize = m_pParticle[0]->m_uchStartSize;
|
||||
m_pParticle[1]->m_flRoll = random->RandomInt( 0, 360 );
|
||||
}
|
||||
}
|
||||
170
game/client/hl2/c_thumper_dust.cpp
Normal file
170
game/client/hl2/c_thumper_dust.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "particlemgr.h"
|
||||
#include "particle_prototype.h"
|
||||
#include "particle_util.h"
|
||||
#include "c_te_particlesystem.h"
|
||||
#include "fx.h"
|
||||
#include "fx_quad.h"
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#include "view.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define THUMPER_DUST_LIFETIME 2.0f
|
||||
#define THUMPER_MAX_PARTICLES 24
|
||||
|
||||
|
||||
extern IPhysicsSurfaceProps *physprops;
|
||||
|
||||
|
||||
class ThumperDustEmitter : public CSimpleEmitter
|
||||
{
|
||||
public:
|
||||
|
||||
ThumperDustEmitter( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
|
||||
|
||||
static ThumperDustEmitter *Create( const char *pDebugName )
|
||||
{
|
||||
return new ThumperDustEmitter( pDebugName );
|
||||
}
|
||||
|
||||
void UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
|
||||
{
|
||||
// Float up when lifetime is half gone.
|
||||
pParticle->m_vecVelocity[2] -= ( 8.0f * timeDelta );
|
||||
|
||||
|
||||
// FIXME: optimize this....
|
||||
pParticle->m_vecVelocity *= ExponentialDecay( 0.9, 0.03, timeDelta );
|
||||
}
|
||||
|
||||
virtual float UpdateRoll( SimpleParticle *pParticle, float timeDelta )
|
||||
{
|
||||
pParticle->m_flRoll += pParticle->m_flRollDelta * timeDelta;
|
||||
|
||||
pParticle->m_flRollDelta += pParticle->m_flRollDelta * ( timeDelta * -4.0f );
|
||||
|
||||
//Cap the minimum roll
|
||||
if ( fabs( pParticle->m_flRollDelta ) < 0.25f )
|
||||
{
|
||||
pParticle->m_flRollDelta = ( pParticle->m_flRollDelta > 0.0f ) ? 0.25f : -0.25f;
|
||||
}
|
||||
|
||||
return pParticle->m_flRoll;
|
||||
}
|
||||
|
||||
virtual float UpdateAlpha( const SimpleParticle *pParticle )
|
||||
{
|
||||
return (pParticle->m_uchStartAlpha/255.0f) + ( (float)(pParticle->m_uchEndAlpha/255.0f) - (float)(pParticle->m_uchStartAlpha/255.0f) ) * (pParticle->m_flLifetime / pParticle->m_flDieTime);
|
||||
}
|
||||
|
||||
private:
|
||||
ThumperDustEmitter( const ThumperDustEmitter & );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bNewEntity - whether or not to start a new entity
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FX_ThumperDust( const CEffectData &data )
|
||||
{
|
||||
Vector vecDustColor;
|
||||
vecDustColor.x = 0.85f;
|
||||
vecDustColor.y = 0.75f;
|
||||
vecDustColor.z = 0.52f;
|
||||
|
||||
CSmartPtr<ThumperDustEmitter> pSimple = ThumperDustEmitter::Create( "thumperdust" );
|
||||
|
||||
C_BaseEntity *pEnt = C_BaseEntity::Instance( data.m_hEntity );
|
||||
if ( pEnt )
|
||||
{
|
||||
Vector vWorldMins, vWorldMaxs;
|
||||
float scale = pEnt->CollisionProp()->BoundingRadius();
|
||||
vWorldMins[0] = data.m_vOrigin[0] - scale;
|
||||
vWorldMins[1] = data.m_vOrigin[1] - scale;
|
||||
vWorldMins[2] = data.m_vOrigin[2] - scale;
|
||||
vWorldMaxs[0] = data.m_vOrigin[0] + scale;
|
||||
vWorldMaxs[1] = data.m_vOrigin[1] + scale;
|
||||
vWorldMaxs[2] = data.m_vOrigin[2] + scale;
|
||||
pSimple->GetBinding().SetBBox( vWorldMins, vWorldMaxs, true );
|
||||
}
|
||||
|
||||
pSimple->SetSortOrigin( data.m_vOrigin );
|
||||
pSimple->SetNearClip( 32, 64 );
|
||||
|
||||
SimpleParticle *pParticle = NULL;
|
||||
|
||||
Vector offset;
|
||||
|
||||
//int numPuffs = IsXbox() ? THUMPER_MAX_PARTICLES/2 : THUMPER_MAX_PARTICLES;
|
||||
int numPuffs = THUMPER_MAX_PARTICLES;
|
||||
|
||||
float flYaw = 0;
|
||||
float flIncr = (2*M_PI) / (float) numPuffs; // Radians
|
||||
Vector forward;
|
||||
Vector vecColor;
|
||||
int i = 0;
|
||||
|
||||
float flScale = MIN( data.m_flScale, 255 );
|
||||
|
||||
// Setup the color for these particles
|
||||
engine->ComputeLighting( data.m_vOrigin, NULL, true, vecColor );
|
||||
VectorLerp( vecColor, vecDustColor, 0.5, vecColor );
|
||||
vecColor *= 255;
|
||||
|
||||
for ( i = 0; i < numPuffs; i++ )
|
||||
{
|
||||
flYaw += flIncr;
|
||||
SinCos( flYaw, &forward.y, &forward.x );
|
||||
forward.z = 0.0f;
|
||||
|
||||
offset = ( RandomVector( -4.0f, 4.0f ) + data.m_vOrigin ) + ( forward * 128.0f );
|
||||
|
||||
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof(SimpleParticle), g_Mat_DustPuff[random->RandomInt(0,1)], offset );
|
||||
if ( pParticle != NULL )
|
||||
{
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = 1.5f;
|
||||
|
||||
Vector dir = (offset - data.m_vOrigin);
|
||||
float length = dir.Length();
|
||||
VectorNormalize( dir );
|
||||
|
||||
pParticle->m_vecVelocity = dir * ( length * 2.0f );
|
||||
pParticle->m_vecVelocity[2] = data.m_flScale / 3;
|
||||
|
||||
pParticle->m_uchColor[0] = vecColor[0];
|
||||
pParticle->m_uchColor[1] = vecColor[1];
|
||||
pParticle->m_uchColor[2] = vecColor[2];
|
||||
|
||||
pParticle->m_uchStartAlpha = random->RandomInt( 64, 96 );
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
|
||||
pParticle->m_uchStartSize = flScale * 0.25f;
|
||||
pParticle->m_uchEndSize = flScale * 0.5f;
|
||||
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -6.0f, 6.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
void ThumperDustCallback( const CEffectData &data )
|
||||
{
|
||||
FX_ThumperDust( data );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "ThumperDust", ThumperDustCallback );
|
||||
931
game/client/hl2/c_vehicle_airboat.cpp
Normal file
931
game/client/hl2/c_vehicle_airboat.cpp
Normal file
@@ -0,0 +1,931 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Client side implementation of the airboat.
|
||||
//
|
||||
// - Dampens motion of driver's view to reduce nausea.
|
||||
// - Autocenters driver's view after a period of inactivity.
|
||||
// - Controls headlights.
|
||||
// - Controls curve parameters for pitch/roll blending.
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_prop_vehicle.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "flashlighteffect.h"
|
||||
#include "movevars_shared.h"
|
||||
#include "ammodef.h"
|
||||
#include "SpriteTrail.h"
|
||||
#include "beamdraw.h"
|
||||
#include "enginesprite.h"
|
||||
#include "fx_quad.h"
|
||||
#include "fx.h"
|
||||
#include "fx_water.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
#include "view.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
#include "c_basehlplayer.h"
|
||||
#include "vgui_controls/Controls.h"
|
||||
#include "vgui/ISurface.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
ConVar r_AirboatViewBlendTo( "r_AirboatViewBlendTo", "1", FCVAR_CHEAT );
|
||||
ConVar r_AirboatViewBlendToScale( "r_AirboatViewBlendToScale", "0.03", FCVAR_CHEAT );
|
||||
ConVar r_AirboatViewBlendToTime( "r_AirboatViewBlendToTime", "1.5", FCVAR_CHEAT );
|
||||
|
||||
ConVar cl_draw_airboat_wake( "cl_draw_airboat_wake", "1", FCVAR_CHEAT );
|
||||
|
||||
// Curve parameters for pitch/roll blending.
|
||||
// NOTE: Must restart (or create a new airboat) after changing these cvars!
|
||||
ConVar r_AirboatRollCurveZero( "r_AirboatRollCurveZero", "90.0", FCVAR_CHEAT ); // Roll less than this is clamped to zero.
|
||||
ConVar r_AirboatRollCurveLinear( "r_AirboatRollCurveLinear", "120.0", FCVAR_CHEAT ); // Roll greater than this is mapped directly.
|
||||
// Spline in between.
|
||||
|
||||
ConVar r_AirboatPitchCurveZero( "r_AirboatPitchCurveZero", "25.0", FCVAR_CHEAT ); // Pitch less than this is clamped to zero.
|
||||
ConVar r_AirboatPitchCurveLinear( "r_AirboatPitchCurveLinear", "60.0", FCVAR_CHEAT ); // Pitch greater than this is mapped directly.
|
||||
// Spline in between.
|
||||
|
||||
ConVar airboat_joy_response_move( "airboat_joy_response_move", "1" ); // Quadratic steering response
|
||||
|
||||
|
||||
#define AIRBOAT_DELTA_LENGTH_MAX 12.0f // 1 foot
|
||||
#define AIRBOAT_FRAMETIME_MIN 1e-6
|
||||
|
||||
#define HEADLIGHT_DISTANCE 1000
|
||||
|
||||
#define MAX_WAKE_POINTS 16
|
||||
#define WAKE_POINT_MASK (MAX_WAKE_POINTS-1)
|
||||
|
||||
#define WAKE_LIFETIME 0.5f
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Client-side Airboat Class
|
||||
//
|
||||
class C_PropAirboat : public C_PropVehicleDriveable
|
||||
{
|
||||
DECLARE_CLASS( C_PropAirboat, C_PropVehicleDriveable );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_INTERPOLATION();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
C_PropAirboat();
|
||||
~C_PropAirboat();
|
||||
|
||||
public:
|
||||
|
||||
// C_BaseEntity
|
||||
virtual void Simulate();
|
||||
|
||||
// IClientVehicle
|
||||
virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd );
|
||||
virtual void OnEnteredVehicle( C_BasePlayer *pPlayer );
|
||||
virtual int GetPrimaryAmmoType() const;
|
||||
virtual int GetPrimaryAmmoClip() const;
|
||||
virtual bool PrimaryAmmoUsesClips() const;
|
||||
virtual int GetPrimaryAmmoCount() const;
|
||||
virtual int GetJoystickResponseCurve() const;
|
||||
|
||||
int DrawModel( int flags );
|
||||
|
||||
// Draws crosshair in the forward direction of the boat
|
||||
void DrawHudElements( );
|
||||
|
||||
private:
|
||||
|
||||
void DrawPropWake( Vector origin, float speed );
|
||||
void DrawPontoonSplash( Vector position, Vector direction, float speed );
|
||||
void DrawPontoonWake( Vector startPos, Vector wakeDir, float wakeLength, float speed);
|
||||
|
||||
void DampenEyePosition( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles );
|
||||
void DampenForwardMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime );
|
||||
void DampenUpMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime );
|
||||
void ComputePDControllerCoefficients( float *pCoefficientsOut, float flFrequency, float flDampening, float flDeltaTime );
|
||||
|
||||
void UpdateHeadlight( void );
|
||||
void UpdateWake( void );
|
||||
int DrawWake( void );
|
||||
void DrawSegment( const BeamSeg_t &beamSeg, const Vector &vNormal );
|
||||
|
||||
TrailPoint_t *GetTrailPoint( int n )
|
||||
{
|
||||
int nIndex = (n + m_nFirstStep) & WAKE_POINT_MASK;
|
||||
return &m_vecSteps[nIndex];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Vector m_vecLastEyePos;
|
||||
Vector m_vecLastEyeTarget;
|
||||
Vector m_vecEyeSpeed;
|
||||
Vector m_vecTargetSpeed;
|
||||
|
||||
float m_flViewAngleDeltaTime;
|
||||
|
||||
bool m_bHeadlightIsOn;
|
||||
int m_nAmmoCount;
|
||||
CHeadlightEffect *m_pHeadlight;
|
||||
|
||||
int m_nExactWaterLevel;
|
||||
|
||||
TrailPoint_t m_vecSteps[MAX_WAKE_POINTS];
|
||||
int m_nFirstStep;
|
||||
int m_nStepCount;
|
||||
float m_flUpdateTime;
|
||||
|
||||
TimedEvent m_SplashTime;
|
||||
CMeshBuilder m_Mesh;
|
||||
|
||||
Vector m_vecPhysVelocity;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_PropAirboat, DT_PropAirboat, CPropAirboat )
|
||||
RecvPropBool( RECVINFO( m_bHeadlightIsOn ) ),
|
||||
RecvPropInt( RECVINFO( m_nAmmoCount ) ),
|
||||
RecvPropInt( RECVINFO( m_nExactWaterLevel ) ),
|
||||
RecvPropInt( RECVINFO( m_nWaterLevel ) ),
|
||||
RecvPropVector( RECVINFO( m_vecPhysVelocity ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
BEGIN_DATADESC( C_PropAirboat )
|
||||
DEFINE_FIELD( m_vecLastEyePos, FIELD_POSITION_VECTOR ),
|
||||
DEFINE_FIELD( m_vecLastEyeTarget, FIELD_POSITION_VECTOR ),
|
||||
DEFINE_FIELD( m_vecEyeSpeed, FIELD_VECTOR ),
|
||||
DEFINE_FIELD( m_vecTargetSpeed, FIELD_VECTOR ),
|
||||
//DEFINE_FIELD( m_flViewAngleDeltaTime, FIELD_FLOAT ),
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PropAirboat::C_PropAirboat()
|
||||
{
|
||||
m_vecEyeSpeed.Init();
|
||||
m_flViewAngleDeltaTime = 0.0f;
|
||||
m_pHeadlight = NULL;
|
||||
|
||||
m_ViewSmoothingData.flPitchCurveZero = r_AirboatPitchCurveZero.GetFloat();
|
||||
m_ViewSmoothingData.flPitchCurveLinear = r_AirboatPitchCurveLinear.GetFloat();
|
||||
m_ViewSmoothingData.flRollCurveZero = r_AirboatRollCurveZero.GetFloat();
|
||||
m_ViewSmoothingData.flRollCurveLinear = r_AirboatRollCurveLinear.GetFloat();
|
||||
|
||||
m_ViewSmoothingData.rollLockData.flLockInterval = 1.5;
|
||||
m_ViewSmoothingData.rollLockData.flUnlockBlendInterval = 1.0;
|
||||
|
||||
m_ViewSmoothingData.pitchLockData.flLockInterval = 1.5;
|
||||
m_ViewSmoothingData.pitchLockData.flUnlockBlendInterval = 1.0;
|
||||
|
||||
m_nFirstStep = 0;
|
||||
m_nStepCount = 0;
|
||||
m_SplashTime.Init( 60 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Deconstructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PropAirboat::~C_PropAirboat()
|
||||
{
|
||||
if (m_pHeadlight)
|
||||
{
|
||||
delete m_pHeadlight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draws the ammo for the airboat
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_PropAirboat::GetPrimaryAmmoType() const
|
||||
{
|
||||
if ( m_nAmmoCount < 0 )
|
||||
return -1;
|
||||
|
||||
int nAmmoType = GetAmmoDef()->Index( "AirboatGun" );
|
||||
return nAmmoType;
|
||||
}
|
||||
|
||||
int C_PropAirboat::GetPrimaryAmmoCount() const
|
||||
{
|
||||
return m_nAmmoCount;
|
||||
}
|
||||
|
||||
bool C_PropAirboat::PrimaryAmmoUsesClips() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int C_PropAirboat::GetPrimaryAmmoClip() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// The airboat prefers a more peppy response curve for joystick control.
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_PropAirboat::GetJoystickResponseCurve() const
|
||||
{
|
||||
return airboat_joy_response_move.GetInt();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draws crosshair in the forward direction of the boat
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::DrawHudElements( )
|
||||
{
|
||||
BaseClass::DrawHudElements();
|
||||
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
|
||||
CHudTexture *pIcon = gHUD.GetIcon( IsX360() ? "crosshair_default" : "plushair" );
|
||||
if ( pIcon != NULL )
|
||||
{
|
||||
float x, y;
|
||||
Vector screen;
|
||||
|
||||
int vx, vy, vw, vh;
|
||||
vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh );
|
||||
float screenWidth = vw;
|
||||
float screenHeight = vh;
|
||||
|
||||
x = screenWidth/2;
|
||||
y = screenHeight/2;
|
||||
|
||||
int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
|
||||
Vector vehicleEyeOrigin;
|
||||
QAngle vehicleEyeAngles;
|
||||
GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
|
||||
|
||||
// Only worry about yaw.
|
||||
vehicleEyeAngles.x = vehicleEyeAngles.z = 0.0f;
|
||||
|
||||
Vector vecForward;
|
||||
AngleVectors( vehicleEyeAngles, &vecForward );
|
||||
VectorMA( vehicleEyeOrigin, 100.0f, vecForward, vehicleEyeOrigin );
|
||||
|
||||
ScreenTransform( vehicleEyeOrigin, screen );
|
||||
x += 0.5 * screen[0] * screenWidth + 0.5;
|
||||
y -= 0.5 * screen[1] * screenHeight + 0.5;
|
||||
|
||||
x -= pIcon->Width() / 2;
|
||||
y -= pIcon->Height() / 2;
|
||||
|
||||
pIcon->DrawSelf( x, y, gHUD.m_clrNormal );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Blend view angles.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
|
||||
{
|
||||
if ( r_AirboatViewBlendTo.GetInt() )
|
||||
{
|
||||
//
|
||||
// Autocenter the view after a period of no mouse movement while throttling.
|
||||
//
|
||||
bool bResetViewAngleTime = false;
|
||||
|
||||
if ( ( pCmd->mousedx != 0 || pCmd->mousedy != 0 ) || ( fabsf( m_flThrottle ) < 0.01f ) )
|
||||
{
|
||||
if ( IsX360() )
|
||||
{
|
||||
// Only reset this if there isn't an autoaim target!
|
||||
C_BaseHLPlayer *pLocalHLPlayer = (C_BaseHLPlayer *)pLocalPlayer;
|
||||
if ( pLocalHLPlayer )
|
||||
{
|
||||
// Get the autoaim target.
|
||||
CBaseEntity *pTarget = pLocalHLPlayer->m_HL2Local.m_hAutoAimTarget.Get();
|
||||
|
||||
if( !pTarget )
|
||||
{
|
||||
bResetViewAngleTime = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bResetViewAngleTime = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( bResetViewAngleTime )
|
||||
{
|
||||
m_flViewAngleDeltaTime = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flViewAngleDeltaTime += gpGlobals->frametime;
|
||||
}
|
||||
|
||||
if ( m_flViewAngleDeltaTime > r_AirboatViewBlendToTime.GetFloat() )
|
||||
{
|
||||
// Blend the view angles.
|
||||
int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
|
||||
Vector vehicleEyeOrigin;
|
||||
QAngle vehicleEyeAngles;
|
||||
GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
|
||||
|
||||
QAngle outAngles;
|
||||
InterpolateAngles( pCmd->viewangles, vehicleEyeAngles, outAngles, r_AirboatViewBlendToScale.GetFloat() );
|
||||
pCmd->viewangles = outAngles;
|
||||
}
|
||||
}
|
||||
|
||||
BaseClass::UpdateViewAngles( pLocalPlayer, pCmd );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::DampenEyePosition( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles )
|
||||
{
|
||||
// Get the frametime. (Check to see if enough time has passed to warrent dampening).
|
||||
float flFrameTime = gpGlobals->frametime;
|
||||
if ( flFrameTime < AIRBOAT_FRAMETIME_MIN )
|
||||
{
|
||||
vecVehicleEyePos = m_vecLastEyePos;
|
||||
DampenUpMotion( vecVehicleEyePos, vecVehicleEyeAngles, 0.0f );
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep static the sideways motion.
|
||||
|
||||
// Dampen forward/backward motion.
|
||||
DampenForwardMotion( vecVehicleEyePos, vecVehicleEyeAngles, flFrameTime );
|
||||
|
||||
// Blend up/down motion.
|
||||
DampenUpMotion( vecVehicleEyePos, vecVehicleEyeAngles, flFrameTime );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Use the controller as follows:
|
||||
// speed += ( pCoefficientsOut[0] * ( targetPos - currentPos ) + pCoefficientsOut[1] * ( targetSpeed - currentSpeed ) ) * flDeltaTime;
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::ComputePDControllerCoefficients( float *pCoefficientsOut,
|
||||
float flFrequency, float flDampening,
|
||||
float flDeltaTime )
|
||||
{
|
||||
float flKs = 9.0f * flFrequency * flFrequency;
|
||||
float flKd = 4.5f * flFrequency * flDampening;
|
||||
|
||||
float flScale = 1.0f / ( 1.0f + flKd * flDeltaTime + flKs * flDeltaTime * flDeltaTime );
|
||||
|
||||
pCoefficientsOut[0] = flKs * flScale;
|
||||
pCoefficientsOut[1] = ( flKd + flKs * flDeltaTime ) * flScale;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::DampenForwardMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime )
|
||||
{
|
||||
// vecVehicleEyePos = real eye position this frame
|
||||
|
||||
// m_vecLastEyePos = eye position last frame
|
||||
// m_vecEyeSpeed = eye speed last frame
|
||||
// vecPredEyePos = predicted eye position this frame (assuming no acceleration - it will get that from the pd controller).
|
||||
// vecPredEyeSpeed = predicted eye speed
|
||||
Vector vecPredEyePos = m_vecLastEyePos + m_vecEyeSpeed * flFrameTime;
|
||||
Vector vecPredEyeSpeed = m_vecEyeSpeed;
|
||||
|
||||
// m_vecLastEyeTarget = real eye position last frame (used for speed calculation).
|
||||
// Calculate the approximate speed based on the current vehicle eye position and the eye position last frame.
|
||||
Vector vecVehicleEyeSpeed = ( vecVehicleEyePos - m_vecLastEyeTarget ) / flFrameTime;
|
||||
m_vecLastEyeTarget = vecVehicleEyePos;
|
||||
if (vecVehicleEyeSpeed.Length() == 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the delta between the predicted eye position and speed and the current eye position and speed.
|
||||
Vector vecDeltaSpeed = vecVehicleEyeSpeed - vecPredEyeSpeed;
|
||||
Vector vecDeltaPos = vecVehicleEyePos - vecPredEyePos;
|
||||
|
||||
// Forward vector.
|
||||
Vector vecForward;
|
||||
AngleVectors( vecVehicleEyeAngles, &vecForward );
|
||||
|
||||
float flDeltaLength = vecDeltaPos.Length();
|
||||
if ( flDeltaLength > AIRBOAT_DELTA_LENGTH_MAX )
|
||||
{
|
||||
// Clamp.
|
||||
float flDelta = flDeltaLength - AIRBOAT_DELTA_LENGTH_MAX;
|
||||
if ( flDelta > 40.0f )
|
||||
{
|
||||
// This part is a bit of a hack to get rid of large deltas (at level load, etc.).
|
||||
m_vecLastEyePos = vecVehicleEyePos;
|
||||
m_vecEyeSpeed = vecVehicleEyeSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Position clamp.
|
||||
float flRatio = AIRBOAT_DELTA_LENGTH_MAX / flDeltaLength;
|
||||
vecDeltaPos *= flRatio;
|
||||
Vector vecForwardOffset = vecForward * ( vecForward.Dot( vecDeltaPos ) );
|
||||
vecVehicleEyePos -= vecForwardOffset;
|
||||
m_vecLastEyePos = vecVehicleEyePos;
|
||||
|
||||
// Speed clamp.
|
||||
vecDeltaSpeed *= flRatio;
|
||||
float flCoefficients[2];
|
||||
ComputePDControllerCoefficients( flCoefficients, r_AirboatViewDampenFreq.GetFloat(), r_AirboatViewDampenDamp.GetFloat(), flFrameTime );
|
||||
m_vecEyeSpeed += ( ( flCoefficients[0] * vecDeltaPos + flCoefficients[1] * vecDeltaSpeed ) * flFrameTime );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Generate an updated (dampening) speed for use in next frames position prediction.
|
||||
float flCoefficients[2];
|
||||
ComputePDControllerCoefficients( flCoefficients, r_AirboatViewDampenFreq.GetFloat(), r_AirboatViewDampenDamp.GetFloat(), flFrameTime );
|
||||
m_vecEyeSpeed += ( ( flCoefficients[0] * vecDeltaPos + flCoefficients[1] * vecDeltaSpeed ) * flFrameTime );
|
||||
|
||||
// Save off data for next frame.
|
||||
m_vecLastEyePos = vecPredEyePos;
|
||||
|
||||
// Move eye forward/backward.
|
||||
Vector vecForwardOffset = vecForward * ( vecForward.Dot( vecDeltaPos ) );
|
||||
vecVehicleEyePos -= vecForwardOffset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::DampenUpMotion( Vector &vecVehicleEyePos, QAngle &vecVehicleEyeAngles, float flFrameTime )
|
||||
{
|
||||
// Get up vector.
|
||||
Vector vecUp;
|
||||
AngleVectors( vecVehicleEyeAngles, NULL, NULL, &vecUp );
|
||||
vecUp.z = clamp( vecUp.z, 0.0f, vecUp.z );
|
||||
vecVehicleEyePos.z += r_AirboatViewZHeight.GetFloat() * vecUp.z;
|
||||
|
||||
// NOTE: Should probably use some damped equation here.
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::OnEnteredVehicle( C_BasePlayer *pPlayer )
|
||||
{
|
||||
int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
|
||||
Vector vehicleEyeOrigin;
|
||||
QAngle vehicleEyeAngles;
|
||||
GetAttachment( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
|
||||
|
||||
m_vecLastEyeTarget = vehicleEyeOrigin;
|
||||
m_vecLastEyePos = vehicleEyeOrigin;
|
||||
m_vecEyeSpeed = vec3_origin;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::Simulate()
|
||||
{
|
||||
UpdateHeadlight();
|
||||
UpdateWake();
|
||||
|
||||
BaseClass::Simulate();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Creates, destroys, and updates the headlight effect as needed.
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::UpdateHeadlight()
|
||||
{
|
||||
if (m_bHeadlightIsOn)
|
||||
{
|
||||
if (!m_pHeadlight)
|
||||
{
|
||||
// Turned on the headlight; create it.
|
||||
m_pHeadlight = new CHeadlightEffect();
|
||||
|
||||
if (!m_pHeadlight)
|
||||
return;
|
||||
|
||||
m_pHeadlight->TurnOn();
|
||||
}
|
||||
|
||||
// The headlight is emitted from an attachment point so that it can move
|
||||
// as we turn the handlebars.
|
||||
int nHeadlightIndex = LookupAttachment( "vehicle_headlight" );
|
||||
|
||||
Vector vecLightPos;
|
||||
QAngle angLightDir;
|
||||
GetAttachment(nHeadlightIndex, vecLightPos, angLightDir);
|
||||
|
||||
Vector vecLightDir, vecLightRight, vecLightUp;
|
||||
AngleVectors( angLightDir, &vecLightDir, &vecLightRight, &vecLightUp );
|
||||
|
||||
// Update the light with the new position and direction.
|
||||
m_pHeadlight->UpdateLight( vecLightPos, vecLightDir, vecLightRight, vecLightUp, HEADLIGHT_DISTANCE );
|
||||
}
|
||||
else if (m_pHeadlight)
|
||||
{
|
||||
// Turned off the headlight; delete it.
|
||||
delete m_pHeadlight;
|
||||
m_pHeadlight = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::UpdateWake( void )
|
||||
{
|
||||
if ( gpGlobals->frametime <= 0.0f )
|
||||
return;
|
||||
|
||||
// Can't update too quickly
|
||||
if ( m_flUpdateTime > gpGlobals->curtime )
|
||||
return;
|
||||
|
||||
Vector screenPos = GetRenderOrigin();
|
||||
screenPos.z = m_nExactWaterLevel;
|
||||
|
||||
TrailPoint_t *pLast = m_nStepCount ? GetTrailPoint( m_nStepCount-1 ) : NULL;
|
||||
if ( ( pLast == NULL ) || ( pLast->m_vecScreenPos.DistToSqr( screenPos ) > 4.0f ) )
|
||||
{
|
||||
// If we're over our limit, steal the last point and put it up front
|
||||
if ( m_nStepCount >= MAX_WAKE_POINTS )
|
||||
{
|
||||
--m_nStepCount;
|
||||
++m_nFirstStep;
|
||||
}
|
||||
|
||||
// Save off its screen position, not its world position
|
||||
TrailPoint_t *pNewPoint = GetTrailPoint( m_nStepCount );
|
||||
pNewPoint->m_vecScreenPos = screenPos + Vector( 0, 0, 2 );
|
||||
pNewPoint->m_flDieTime = gpGlobals->curtime + WAKE_LIFETIME;
|
||||
pNewPoint->m_flWidthVariance = random->RandomFloat( -16, 16 );
|
||||
|
||||
if ( pLast )
|
||||
{
|
||||
pNewPoint->m_flTexCoord = pLast->m_flTexCoord + pLast->m_vecScreenPos.DistTo( screenPos );
|
||||
pNewPoint->m_flTexCoord = fmod( pNewPoint->m_flTexCoord, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
pNewPoint->m_flTexCoord = 0.0f;
|
||||
}
|
||||
|
||||
++m_nStepCount;
|
||||
}
|
||||
|
||||
// Don't update again for a bit
|
||||
m_flUpdateTime = gpGlobals->curtime + ( 0.5f / (float) MAX_WAKE_POINTS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &beamSeg -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::DrawSegment( const BeamSeg_t &beamSeg, const Vector &vNormal )
|
||||
{
|
||||
// Build the endpoints.
|
||||
Vector vPoint1, vPoint2;
|
||||
VectorMA( beamSeg.m_vPos, beamSeg.m_flWidth*0.5f, vNormal, vPoint1 );
|
||||
VectorMA( beamSeg.m_vPos, -beamSeg.m_flWidth*0.5f, vNormal, vPoint2 );
|
||||
|
||||
// Specify the points.
|
||||
m_Mesh.Position3fv( vPoint1.Base() );
|
||||
m_Mesh.Color4f( VectorExpand( beamSeg.m_vColor ), beamSeg.m_flAlpha );
|
||||
m_Mesh.TexCoord2f( 0, 0, beamSeg.m_flTexCoord );
|
||||
m_Mesh.TexCoord2f( 1, 0, beamSeg.m_flTexCoord );
|
||||
m_Mesh.AdvanceVertex();
|
||||
|
||||
m_Mesh.Position3fv( vPoint2.Base() );
|
||||
m_Mesh.Color4f( VectorExpand( beamSeg.m_vColor ), beamSeg.m_flAlpha );
|
||||
m_Mesh.TexCoord2f( 0, 1, beamSeg.m_flTexCoord );
|
||||
m_Mesh.TexCoord2f( 1, 1, beamSeg.m_flTexCoord );
|
||||
m_Mesh.AdvanceVertex();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : position -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::DrawPontoonSplash( Vector origin, Vector direction, float speed )
|
||||
{
|
||||
Vector offset;
|
||||
|
||||
CSmartPtr<CSplashParticle> pSimple = CSplashParticle::Create( "splish" );
|
||||
pSimple->SetSortOrigin( origin );
|
||||
|
||||
SimpleParticle *pParticle;
|
||||
|
||||
Vector color = Vector( 0.8f, 0.8f, 0.75f );
|
||||
float colorRamp;
|
||||
|
||||
float flScale = RemapVal( speed, 64, 256, 0.75f, 1.0f );
|
||||
|
||||
PMaterialHandle hMaterial;
|
||||
|
||||
float tempDelta = gpGlobals->frametime;
|
||||
|
||||
while( m_SplashTime.NextEvent( tempDelta ) )
|
||||
{
|
||||
if ( random->RandomInt( 0, 1 ) )
|
||||
{
|
||||
hMaterial = ParticleMgr()->GetPMaterial( "effects/splash1" );
|
||||
}
|
||||
else
|
||||
{
|
||||
hMaterial = ParticleMgr()->GetPMaterial( "effects/splash2" );
|
||||
}
|
||||
|
||||
offset = RandomVector( -8.0f * flScale, 8.0f * flScale );
|
||||
offset[2] = 0.0f;
|
||||
offset += origin;
|
||||
|
||||
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), hMaterial, offset );
|
||||
|
||||
if ( pParticle == NULL )
|
||||
continue;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = 0.25f;
|
||||
|
||||
pParticle->m_vecVelocity.Random( -0.4f, 0.4f );
|
||||
pParticle->m_vecVelocity += (direction*5.0f+Vector(0,0,1));
|
||||
|
||||
VectorNormalize( pParticle->m_vecVelocity );
|
||||
|
||||
pParticle->m_vecVelocity *= speed + random->RandomFloat( -128.0f, 128.0f );
|
||||
|
||||
colorRamp = random->RandomFloat( 0.75f, 1.25f );
|
||||
|
||||
pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f;
|
||||
pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f;
|
||||
pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f;
|
||||
|
||||
pParticle->m_uchStartSize = random->RandomFloat( 8, 16 ) * flScale;
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize * 2;
|
||||
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 0;
|
||||
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta = random->RandomFloat( -4.0f, 4.0f );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : Vector startPos -
|
||||
// wakeDir -
|
||||
// wakeLength -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropAirboat::DrawPontoonWake( Vector startPos, Vector wakeDir, float wakeLength, float speed )
|
||||
{
|
||||
#define WAKE_STEPS 6
|
||||
|
||||
Vector wakeStep = wakeDir * ( wakeLength / (float) WAKE_STEPS );
|
||||
Vector origin;
|
||||
float scale;
|
||||
|
||||
IMaterial *pMaterial = materials->FindMaterial( "effects/splashwake1", NULL, false );
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
IMesh* pMesh = pRenderContext->GetDynamicMesh( 0, 0, 0, pMaterial );
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, WAKE_STEPS );
|
||||
|
||||
for ( int i = 0; i < WAKE_STEPS; i++ )
|
||||
{
|
||||
origin = startPos + ( wakeStep * i );
|
||||
origin[0] += random->RandomFloat( -4.0f, 4.0f );
|
||||
origin[1] += random->RandomFloat( -4.0f, 4.0f );
|
||||
origin[2] = m_nExactWaterLevel + 2.0f;
|
||||
|
||||
float scaleRange = RemapVal( i, 0, WAKE_STEPS-1, 32, 64 );
|
||||
scale = scaleRange + ( 8.0f * sin( gpGlobals->curtime * 5 * i ) );
|
||||
|
||||
float alpha = RemapValClamped( speed, 128, 600, 0.05f, 0.25f );
|
||||
float color[4] = { 1.0f, 1.0f, 1.0f, alpha };
|
||||
|
||||
// Needs to be time based so it'll freeze when the game is frozen
|
||||
float yaw = random->RandomFloat( 0, 360 );
|
||||
|
||||
Vector rRight = ( Vector(1,0,0) * cos( DEG2RAD( yaw ) ) ) - ( Vector(0,1,0) * sin( DEG2RAD( yaw ) ) );
|
||||
Vector rUp = ( Vector(1,0,0) * cos( DEG2RAD( yaw+90.0f ) ) ) - ( Vector(0,1,0) * sin( DEG2RAD( yaw+90.0f ) ) );
|
||||
|
||||
Vector point;
|
||||
meshBuilder.Color4fv (color);
|
||||
meshBuilder.TexCoord2f (0, 0, 1);
|
||||
VectorMA (origin, -scale, rRight, point);
|
||||
VectorMA (point, -scale, rUp, point);
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4fv (color);
|
||||
meshBuilder.TexCoord2f (0, 0, 0);
|
||||
VectorMA (origin, scale, rRight, point);
|
||||
VectorMA (point, -scale, rUp, point);
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4fv (color);
|
||||
meshBuilder.TexCoord2f (0, 1, 0);
|
||||
VectorMA (origin, scale, rRight, point);
|
||||
VectorMA (point, scale, rUp, point);
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4fv (color);
|
||||
meshBuilder.TexCoord2f (0, 1, 1);
|
||||
VectorMA (origin, -scale, rRight, point);
|
||||
VectorMA (point, scale, rUp, point);
|
||||
meshBuilder.Position3fv (point.Base());
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_PropAirboat::DrawWake( void )
|
||||
{
|
||||
if ( cl_draw_airboat_wake.GetBool() == false )
|
||||
return 0;
|
||||
|
||||
// Make sure we're in water...
|
||||
if ( GetWaterLevel() == 0 )
|
||||
return 0;
|
||||
|
||||
//FIXME: For now, we don't draw slime this way
|
||||
if ( GetWaterLevel() == 2 )
|
||||
return 0;
|
||||
|
||||
bool bDriven = ( GetPassenger( VEHICLE_ROLE_DRIVER ) != NULL );
|
||||
|
||||
Vector vehicleDir = m_vecPhysVelocity;
|
||||
float vehicleSpeed = VectorNormalize( vehicleDir );
|
||||
|
||||
Vector vecPontoonFrontLeft;
|
||||
Vector vecPontoonFrontRight;
|
||||
Vector vecPontoonRearLeft;
|
||||
Vector vecPontoonRearRight;
|
||||
Vector vecSplashPoint;
|
||||
|
||||
QAngle fooAngles;
|
||||
|
||||
//FIXME: This lookup should be cached off
|
||||
// Get all attachments
|
||||
GetAttachment( LookupAttachment( "raytrace_fl" ), vecPontoonFrontLeft, fooAngles );
|
||||
GetAttachment( LookupAttachment( "raytrace_fr" ), vecPontoonFrontRight, fooAngles );
|
||||
GetAttachment( LookupAttachment( "raytrace_rl" ), vecPontoonRearLeft, fooAngles );
|
||||
GetAttachment( LookupAttachment( "raytrace_rr" ), vecPontoonRearRight, fooAngles );
|
||||
GetAttachment( LookupAttachment( "splash_pt" ), vecSplashPoint, fooAngles );
|
||||
|
||||
// Find the direction of the pontoons
|
||||
Vector vecLeftWakeDir = ( vecPontoonRearLeft - vecPontoonFrontLeft );
|
||||
Vector vecRightWakeDir = ( vecPontoonRearRight - vecPontoonFrontRight );
|
||||
|
||||
// Find the pontoon's size
|
||||
float flWakeLeftLength = VectorNormalize( vecLeftWakeDir );
|
||||
float flWakeRightLength = VectorNormalize( vecRightWakeDir );
|
||||
|
||||
vecPontoonFrontLeft.z = m_nExactWaterLevel;
|
||||
vecPontoonFrontRight.z = m_nExactWaterLevel;
|
||||
|
||||
if ( bDriven && vehicleSpeed > 128.0f )
|
||||
{
|
||||
DrawPontoonWake( vecPontoonFrontLeft, vecLeftWakeDir, flWakeLeftLength, vehicleSpeed );
|
||||
DrawPontoonWake( vecPontoonFrontRight, vecRightWakeDir, flWakeRightLength, vehicleSpeed );
|
||||
|
||||
Vector vecSplashDir;
|
||||
Vector vForward;
|
||||
GetVectors( &vForward, NULL, NULL );
|
||||
|
||||
if ( m_vecPhysVelocity.x < -64.0f )
|
||||
{
|
||||
vecSplashDir = vecLeftWakeDir - vForward;
|
||||
VectorNormalize( vecSplashDir );
|
||||
|
||||
// Don't do this if we're going backwards
|
||||
if ( m_vecPhysVelocity.y > 0.0f )
|
||||
{
|
||||
DrawPontoonSplash( vecPontoonFrontLeft + ( vecLeftWakeDir * 1.0f ), vecSplashDir, m_vecPhysVelocity.y );
|
||||
}
|
||||
}
|
||||
else if ( m_vecPhysVelocity.x > 64.0f )
|
||||
{
|
||||
vecSplashDir = vecRightWakeDir + vForward;
|
||||
VectorNormalize( vecSplashDir );
|
||||
|
||||
// Don't do this if we're going backwards
|
||||
if ( m_vecPhysVelocity.y > 0.0f )
|
||||
{
|
||||
DrawPontoonSplash( vecPontoonFrontRight + ( vecRightWakeDir * 1.0f ), vecSplashDir, m_vecPhysVelocity.y );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Must have at least one point
|
||||
if ( m_nStepCount <= 1 )
|
||||
return 1;
|
||||
|
||||
IMaterial *pMaterial = materials->FindMaterial( "effects/splashwake4", 0);
|
||||
|
||||
//Bind the material
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial );
|
||||
|
||||
m_Mesh.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, (m_nStepCount-1) * 2 );
|
||||
|
||||
TrailPoint_t *pLast = GetTrailPoint( m_nStepCount - 1 );
|
||||
|
||||
TrailPoint_t currentPoint;
|
||||
currentPoint.m_flDieTime = gpGlobals->curtime + 0.5f;
|
||||
currentPoint.m_vecScreenPos = GetAbsOrigin();
|
||||
currentPoint.m_vecScreenPos[2] = m_nExactWaterLevel + 16;
|
||||
currentPoint.m_flTexCoord = pLast->m_flTexCoord + currentPoint.m_vecScreenPos.DistTo(pLast->m_vecScreenPos);
|
||||
currentPoint.m_flTexCoord = fmod( currentPoint.m_flTexCoord, 1 );
|
||||
currentPoint.m_flWidthVariance = 0.0f;
|
||||
|
||||
TrailPoint_t *pPrevPoint = NULL;
|
||||
|
||||
Vector segDir, normal;
|
||||
|
||||
for ( int i = 0; i <= m_nStepCount; ++i )
|
||||
{
|
||||
// This makes it so that we're always drawing to the current location
|
||||
TrailPoint_t *pPoint = (i != m_nStepCount) ? GetTrailPoint(i) : ¤tPoint;
|
||||
|
||||
float flLifePerc = RemapValClamped( ( pPoint->m_flDieTime - gpGlobals->curtime ), 0, WAKE_LIFETIME, 0.0f, 1.0f );
|
||||
|
||||
BeamSeg_t curSeg;
|
||||
curSeg.m_vColor.x = curSeg.m_vColor.y = curSeg.m_vColor.z = 1.0f;
|
||||
|
||||
float flAlphaFade = flLifePerc;
|
||||
float alpha = RemapValClamped( fabs( m_vecPhysVelocity.y ), 128, 600, 0.0f, 1.0f );
|
||||
|
||||
curSeg.m_flAlpha = 0.25f;
|
||||
curSeg.m_flAlpha *= flAlphaFade * alpha;
|
||||
|
||||
curSeg.m_vPos = pPoint->m_vecScreenPos;
|
||||
|
||||
float widthBase = SimpleSplineRemapVal( fabs( m_vecPhysVelocity.y ), 128, 600, 32, 48 );
|
||||
|
||||
curSeg.m_flWidth = Lerp( flLifePerc, widthBase*6, widthBase );
|
||||
curSeg.m_flWidth += pPoint->m_flWidthVariance;
|
||||
|
||||
if ( curSeg.m_flWidth < 0.0f )
|
||||
{
|
||||
curSeg.m_flWidth = 0.0f;
|
||||
}
|
||||
|
||||
curSeg.m_flTexCoord = pPoint->m_flTexCoord;
|
||||
|
||||
if ( pPrevPoint != NULL )
|
||||
{
|
||||
segDir = ( pPrevPoint->m_vecScreenPos - pPoint->m_vecScreenPos );
|
||||
VectorNormalize( segDir );
|
||||
|
||||
normal = CrossProduct( segDir, Vector( 0, 0, -1 ) );
|
||||
|
||||
DrawSegment( curSeg, normal );
|
||||
}
|
||||
|
||||
pPrevPoint = pPoint;
|
||||
}
|
||||
|
||||
m_Mesh.End();
|
||||
pMesh->Draw();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_PropAirboat::DrawModel( int flags )
|
||||
{
|
||||
if ( BaseClass::DrawModel( flags ) == false )
|
||||
return 0;
|
||||
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
return DrawWake();
|
||||
}
|
||||
187
game/client/hl2/c_vehicle_cannon.cpp
Normal file
187
game/client/hl2/c_vehicle_cannon.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <Color.h>
|
||||
#include "c_vehicle_crane.h"
|
||||
#include "view.h"
|
||||
#include "vehicle_viewblend_shared.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
int ScreenTransform( const Vector& point, Vector& screen );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_PropCannon : public C_BaseAnimating, public IClientVehicle
|
||||
{
|
||||
|
||||
DECLARE_CLASS( C_PropCannon, C_BaseAnimating );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
C_PropCannon();
|
||||
|
||||
void PreDataUpdate( DataUpdateType_t updateType );
|
||||
|
||||
public:
|
||||
|
||||
// IClientVehicle overrides.
|
||||
virtual void GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles, float *pFOV = NULL );
|
||||
virtual void GetVehicleFOV( float &flFOV ) { flFOV = 0.0f; }
|
||||
virtual void DrawHudElements();
|
||||
virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
|
||||
virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd ) {}
|
||||
virtual C_BaseCombatCharacter *GetPassenger( int nRole );
|
||||
virtual int GetPassengerRole( C_BaseCombatCharacter *pPassenger );
|
||||
virtual void GetVehicleClipPlanes( float &flZNear, float &flZFar ) const;
|
||||
virtual int GetPrimaryAmmoType() const { return -1; }
|
||||
virtual int GetPrimaryAmmoCount() const { return -1; }
|
||||
virtual int GetPrimaryAmmoClip() const { return -1; }
|
||||
virtual bool PrimaryAmmoUsesClips() const { return false; }
|
||||
virtual int GetJoystickResponseCurve() const { return 0; }
|
||||
|
||||
public:
|
||||
|
||||
// C_BaseEntity overrides.
|
||||
virtual IClientVehicle* GetClientVehicle() { return this; }
|
||||
virtual C_BaseEntity *GetVehicleEnt() { return this; }
|
||||
virtual void SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) {}
|
||||
virtual void ProcessMovement( C_BasePlayer *pPlayer, CMoveData *pMoveData ) {}
|
||||
virtual void FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move ) {}
|
||||
virtual bool IsPredicted() const { return false; }
|
||||
virtual void ItemPostFrame( C_BasePlayer *pPlayer ) {}
|
||||
virtual bool IsSelfAnimating() { return false; };
|
||||
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||
|
||||
private:
|
||||
|
||||
CHandle<C_BasePlayer> m_hPlayer;
|
||||
CHandle<C_BasePlayer> m_hPrevPlayer;
|
||||
|
||||
bool m_bEnterAnimOn;
|
||||
bool m_bExitAnimOn;
|
||||
Vector m_vecEyeExitEndpoint;
|
||||
|
||||
Vector m_vecOldShadowDir;
|
||||
|
||||
ViewSmoothingData_t m_ViewSmoothingData;
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_PropCannon, DT_PropCannon, CPropCannon)
|
||||
RecvPropEHandle( RECVINFO(m_hPlayer) ),
|
||||
RecvPropBool( RECVINFO( m_bEnterAnimOn ) ),
|
||||
RecvPropBool( RECVINFO( m_bExitAnimOn ) ),
|
||||
RecvPropVector( RECVINFO( m_vecEyeExitEndpoint ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
BEGIN_DATADESC( C_PropCannon )
|
||||
DEFINE_EMBEDDED( m_ViewSmoothingData ),
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
#define ROLL_CURVE_ZERO 5 // roll less than this is clamped to zero
|
||||
#define ROLL_CURVE_LINEAR 45 // roll greater than this is copied out
|
||||
|
||||
#define PITCH_CURVE_ZERO 10 // pitch less than this is clamped to zero
|
||||
#define PITCH_CURVE_LINEAR 45 // pitch greater than this is copied out
|
||||
// spline in between
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PropCannon::C_PropCannon( void )
|
||||
{
|
||||
memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) );
|
||||
m_ViewSmoothingData.pVehicle = this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCannon::PreDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PreDataUpdate( updateType );
|
||||
|
||||
m_hPrevPlayer = m_hPlayer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseCombatCharacter *C_PropCannon::GetPassenger( int nRole )
|
||||
{
|
||||
if ( nRole == VEHICLE_ROLE_DRIVER )
|
||||
return m_hPlayer.Get();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the role of the passenger
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_PropCannon::GetPassengerRole( C_BaseCombatCharacter *pPassenger )
|
||||
{
|
||||
if ( m_hPlayer.Get() == pPassenger )
|
||||
return VEHICLE_ROLE_DRIVER;
|
||||
|
||||
return VEHICLE_ROLE_NONE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Modify the player view/camera while in a vehicle
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCannon::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*=NULL*/ )
|
||||
{
|
||||
SharedVehicleViewSmoothing( m_hPlayer,
|
||||
pAbsOrigin, pAbsAngles,
|
||||
m_bEnterAnimOn, m_bExitAnimOn,
|
||||
m_vecEyeExitEndpoint,
|
||||
&m_ViewSmoothingData,
|
||||
pFOV );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Futzes with the clip planes
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCannon::GetVehicleClipPlanes( float &flZNear, float &flZFar ) const
|
||||
{
|
||||
// FIXME: Need something a better long-term, this fixes the buggy.
|
||||
flZNear = 6;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Renders hud elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCannon::DrawHudElements( )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : theMins -
|
||||
// theMaxs -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCannon::GetRenderBounds( Vector &theMins, Vector &theMaxs )
|
||||
{
|
||||
// This is kind of hacky:( Add 660.0 to the y coordinate of the bounding box to
|
||||
// allow for the full extension of the crane arm.
|
||||
BaseClass::GetRenderBounds( theMins, theMaxs );
|
||||
theMaxs.y += 660.0f;
|
||||
}
|
||||
|
||||
151
game/client/hl2/c_vehicle_crane.cpp
Normal file
151
game/client/hl2/c_vehicle_crane.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <Color.h>
|
||||
#include "c_vehicle_crane.h"
|
||||
#include "view.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
int ScreenTransform( const Vector& point, Vector& screen );
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_PropCrane, DT_PropCrane, CPropCrane)
|
||||
RecvPropEHandle( RECVINFO(m_hPlayer) ),
|
||||
RecvPropBool( RECVINFO(m_bMagnetOn) ),
|
||||
RecvPropBool( RECVINFO( m_bEnterAnimOn ) ),
|
||||
RecvPropBool( RECVINFO( m_bExitAnimOn ) ),
|
||||
RecvPropVector( RECVINFO( m_vecEyeExitEndpoint ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
BEGIN_DATADESC( C_PropCrane )
|
||||
DEFINE_EMBEDDED( m_ViewSmoothingData ),
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
#define ROLL_CURVE_ZERO 5 // roll less than this is clamped to zero
|
||||
#define ROLL_CURVE_LINEAR 45 // roll greater than this is copied out
|
||||
|
||||
#define PITCH_CURVE_ZERO 10 // pitch less than this is clamped to zero
|
||||
#define PITCH_CURVE_LINEAR 45 // pitch greater than this is copied out
|
||||
// spline in between
|
||||
|
||||
#define CRANE_FOV 75
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PropCrane::C_PropCrane( void )
|
||||
{
|
||||
memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) );
|
||||
m_ViewSmoothingData.pVehicle = this;
|
||||
m_ViewSmoothingData.flFOV = CRANE_FOV;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCrane::PreDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PreDataUpdate( updateType );
|
||||
|
||||
m_hPrevPlayer = m_hPlayer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCrane::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PostDataUpdate( updateType );
|
||||
|
||||
// Store off the old shadow direction
|
||||
if ( m_hPlayer && !m_hPrevPlayer )
|
||||
{
|
||||
m_vecOldShadowDir = g_pClientShadowMgr->GetShadowDirection();
|
||||
//Vector vecDown = m_vecOldShadowDir - Vector(0,0,0.5);
|
||||
//VectorNormalize( vecDown );
|
||||
Vector vecDown = Vector(0,0,-1);
|
||||
g_pClientShadowMgr->SetShadowDirection( vecDown );
|
||||
}
|
||||
else if ( !m_hPlayer && m_hPrevPlayer )
|
||||
{
|
||||
g_pClientShadowMgr->SetShadowDirection( m_vecOldShadowDir );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseCombatCharacter *C_PropCrane::GetPassenger( int nRole )
|
||||
{
|
||||
if ( nRole == VEHICLE_ROLE_DRIVER )
|
||||
return m_hPlayer.Get();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the role of the passenger
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_PropCrane::GetPassengerRole( C_BaseCombatCharacter *pPassenger )
|
||||
{
|
||||
if ( m_hPlayer.Get() == pPassenger )
|
||||
return VEHICLE_ROLE_DRIVER;
|
||||
|
||||
return VEHICLE_ROLE_NONE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Modify the player view/camera while in a vehicle
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCrane::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*=NULL*/ )
|
||||
{
|
||||
SharedVehicleViewSmoothing( m_hPlayer,
|
||||
pAbsOrigin, pAbsAngles,
|
||||
m_bEnterAnimOn, m_bExitAnimOn,
|
||||
m_vecEyeExitEndpoint,
|
||||
&m_ViewSmoothingData,
|
||||
pFOV );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Futzes with the clip planes
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCrane::GetVehicleClipPlanes( float &flZNear, float &flZFar ) const
|
||||
{
|
||||
// FIXME: Need something a better long-term, this fixes the buggy.
|
||||
flZNear = 6;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Renders hud elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCrane::DrawHudElements( )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : theMins -
|
||||
// theMaxs -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropCrane::GetRenderBounds( Vector &theMins, Vector &theMaxs )
|
||||
{
|
||||
// This is kind of hacky:( Add 660.0 to the y coordinate of the bounding box to
|
||||
// allow for the full extension of the crane arm.
|
||||
BaseClass::GetRenderBounds( theMins, theMaxs );
|
||||
theMaxs.y += 660.0f;
|
||||
}
|
||||
|
||||
80
game/client/hl2/c_vehicle_crane.h
Normal file
80
game/client/hl2/c_vehicle_crane.h
Normal file
@@ -0,0 +1,80 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "iclientvehicle.h"
|
||||
#include "vehicle_viewblend_shared.h"
|
||||
|
||||
#ifndef C_VEHICLE_CRANE_H
|
||||
#define C_VEHICLE_CRANE_H
|
||||
#pragma once
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_PropCrane : public C_BaseAnimating, public IClientVehicle
|
||||
{
|
||||
|
||||
DECLARE_CLASS( C_PropCrane, C_BaseAnimating );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
C_PropCrane();
|
||||
|
||||
void PreDataUpdate( DataUpdateType_t updateType );
|
||||
void PostDataUpdate( DataUpdateType_t updateType );
|
||||
|
||||
bool IsMagnetOn( void ) { return m_bMagnetOn; }
|
||||
|
||||
public:
|
||||
|
||||
// IClientVehicle overrides.
|
||||
virtual void GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles, float *pFOV =NULL );
|
||||
virtual void GetVehicleFOV( float &flFOV ) { flFOV = 0.0f; }
|
||||
virtual void DrawHudElements();
|
||||
virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
|
||||
virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd ) {}
|
||||
virtual C_BaseCombatCharacter* GetPassenger( int nRole );
|
||||
virtual int GetPassengerRole( C_BaseCombatCharacter *pPassenger );
|
||||
virtual void GetVehicleClipPlanes( float &flZNear, float &flZFar ) const;
|
||||
virtual int GetPrimaryAmmoType() const { return -1; }
|
||||
virtual int GetPrimaryAmmoCount() const { return -1; }
|
||||
virtual int GetPrimaryAmmoClip() const { return -1; }
|
||||
virtual bool PrimaryAmmoUsesClips() const { return false; }
|
||||
virtual int GetJoystickResponseCurve() const { return 0; }
|
||||
|
||||
public:
|
||||
|
||||
// C_BaseEntity overrides.
|
||||
virtual IClientVehicle* GetClientVehicle() { return this; }
|
||||
virtual C_BaseEntity *GetVehicleEnt() { return this; }
|
||||
virtual void SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) {}
|
||||
virtual void ProcessMovement( C_BasePlayer *pPlayer, CMoveData *pMoveData ) {}
|
||||
virtual void FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move ) {}
|
||||
virtual bool IsPredicted() const { return false; }
|
||||
virtual void ItemPostFrame( C_BasePlayer *pPlayer ) {}
|
||||
virtual bool IsSelfAnimating() { return false; };
|
||||
virtual void GetRenderBounds( Vector& theMins, Vector& theMaxs );
|
||||
|
||||
private:
|
||||
|
||||
CHandle<C_BasePlayer> m_hPlayer;
|
||||
CHandle<C_BasePlayer> m_hPrevPlayer;
|
||||
|
||||
bool m_bEnterAnimOn;
|
||||
bool m_bExitAnimOn;
|
||||
Vector m_vecEyeExitEndpoint;
|
||||
|
||||
bool m_bMagnetOn;
|
||||
|
||||
Vector m_vecOldShadowDir;
|
||||
|
||||
ViewSmoothingData_t m_ViewSmoothingData;
|
||||
};
|
||||
|
||||
#endif // C_VEHICLE_CRANE_H
|
||||
237
game/client/hl2/c_vehicle_prisoner_pod.cpp
Normal file
237
game/client/hl2/c_vehicle_prisoner_pod.cpp
Normal file
@@ -0,0 +1,237 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "c_physicsprop.h"
|
||||
#include "iclientvehicle.h"
|
||||
#include <vgui_controls/Controls.h>
|
||||
#include <Color.h>
|
||||
#include "vehicle_viewblend_shared.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern float RemapAngleRange( float startInterval, float endInterval, float value );
|
||||
|
||||
|
||||
#define ROLL_CURVE_ZERO 5 // roll less than this is clamped to zero
|
||||
#define ROLL_CURVE_LINEAR 45 // roll greater than this is copied out
|
||||
|
||||
#define PITCH_CURVE_ZERO 10 // pitch less than this is clamped to zero
|
||||
#define PITCH_CURVE_LINEAR 45 // pitch greater than this is copied out
|
||||
// spline in between
|
||||
|
||||
#define POD_VIEW_FOV 90
|
||||
#define POD_VIEW_YAW_MIN -60
|
||||
#define POD_VIEW_YAW_MAX 60
|
||||
#define POD_VIEW_PITCH_MIN -90
|
||||
#define POD_VIEW_PITCH_MAX 38 // Don't let players look down and see that the pod is empty
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class C_PropVehiclePrisonerPod : public C_PhysicsProp, public IClientVehicle
|
||||
{
|
||||
DECLARE_CLASS( C_PropVehiclePrisonerPod, C_PhysicsProp );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_DATADESC();
|
||||
|
||||
C_PropVehiclePrisonerPod();
|
||||
|
||||
void PreDataUpdate( DataUpdateType_t updateType );
|
||||
void PostDataUpdate( DataUpdateType_t updateType );
|
||||
|
||||
public:
|
||||
|
||||
// IClientVehicle overrides.
|
||||
virtual void GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles, float *pFOV = NULL );
|
||||
virtual void GetVehicleFOV( float &flFOV )
|
||||
{
|
||||
flFOV = m_flFOV;
|
||||
}
|
||||
virtual void DrawHudElements();
|
||||
virtual bool IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
|
||||
virtual void UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd );
|
||||
virtual C_BaseCombatCharacter* GetPassenger( int nRole );
|
||||
virtual int GetPassengerRole( C_BaseCombatCharacter *pEnt );
|
||||
virtual void GetVehicleClipPlanes( float &flZNear, float &flZFar ) const;
|
||||
virtual int GetPrimaryAmmoType() const { return -1; }
|
||||
virtual int GetPrimaryAmmoCount() const { return -1; }
|
||||
virtual int GetPrimaryAmmoClip() const { return -1; }
|
||||
virtual bool PrimaryAmmoUsesClips() const { return false; }
|
||||
virtual int GetJoystickResponseCurve() const { return 0; }
|
||||
|
||||
public:
|
||||
|
||||
// C_BaseEntity overrides.
|
||||
virtual IClientVehicle* GetClientVehicle() { return this; }
|
||||
virtual C_BaseEntity *GetVehicleEnt() { return this; }
|
||||
virtual void SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) {}
|
||||
virtual void ProcessMovement( C_BasePlayer *pPlayer, CMoveData *pMoveData ) {}
|
||||
virtual void FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *move ) {}
|
||||
virtual bool IsPredicted() const { return false; }
|
||||
virtual void ItemPostFrame( C_BasePlayer *pPlayer ) {}
|
||||
virtual bool IsSelfAnimating() { return false; };
|
||||
|
||||
private:
|
||||
|
||||
CHandle<C_BasePlayer> m_hPlayer;
|
||||
CHandle<C_BasePlayer> m_hPrevPlayer;
|
||||
|
||||
bool m_bEnterAnimOn;
|
||||
bool m_bExitAnimOn;
|
||||
Vector m_vecEyeExitEndpoint;
|
||||
float m_flFOV; // The current FOV (changes during entry/exit anims).
|
||||
|
||||
ViewSmoothingData_t m_ViewSmoothingData;
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT(C_PropVehiclePrisonerPod, DT_PropVehiclePrisonerPod, CPropVehiclePrisonerPod)
|
||||
RecvPropEHandle( RECVINFO(m_hPlayer) ),
|
||||
RecvPropBool( RECVINFO( m_bEnterAnimOn ) ),
|
||||
RecvPropBool( RECVINFO( m_bExitAnimOn ) ),
|
||||
RecvPropVector( RECVINFO( m_vecEyeExitEndpoint ) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
BEGIN_DATADESC( C_PropVehiclePrisonerPod )
|
||||
DEFINE_EMBEDDED( m_ViewSmoothingData ),
|
||||
END_DATADESC()
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_PropVehiclePrisonerPod::C_PropVehiclePrisonerPod( void )
|
||||
{
|
||||
memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) );
|
||||
|
||||
m_ViewSmoothingData.pVehicle = this;
|
||||
m_ViewSmoothingData.bClampEyeAngles = true;
|
||||
m_ViewSmoothingData.flPitchCurveZero = PITCH_CURVE_ZERO;
|
||||
m_ViewSmoothingData.flPitchCurveLinear = PITCH_CURVE_LINEAR;
|
||||
m_ViewSmoothingData.flRollCurveZero = ROLL_CURVE_ZERO;
|
||||
m_ViewSmoothingData.flRollCurveLinear = ROLL_CURVE_LINEAR;
|
||||
m_ViewSmoothingData.flFOV = POD_VIEW_FOV;
|
||||
|
||||
m_flFOV = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropVehiclePrisonerPod::PreDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PreDataUpdate( updateType );
|
||||
|
||||
m_hPrevPlayer = m_hPlayer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropVehiclePrisonerPod::PostDataUpdate( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::PostDataUpdate( updateType );
|
||||
|
||||
if ( !m_hPlayer && m_hPrevPlayer )
|
||||
{
|
||||
// They have just exited the vehicle.
|
||||
// Sometimes we never reach the end of our exit anim, such as if the
|
||||
// animation doesn't have fadeout 0 specified in the QC, so we fail to
|
||||
// catch it in VehicleViewSmoothing. Catch it here instead.
|
||||
m_ViewSmoothingData.bWasRunningAnim = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_BaseCombatCharacter *C_PropVehiclePrisonerPod::GetPassenger( int nRole )
|
||||
{
|
||||
if ( nRole == VEHICLE_ROLE_DRIVER )
|
||||
return m_hPlayer.Get();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns the role of the passenger
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_PropVehiclePrisonerPod::GetPassengerRole( C_BaseCombatCharacter *pPassenger )
|
||||
{
|
||||
if ( m_hPlayer.Get() == pPassenger )
|
||||
return VEHICLE_ROLE_DRIVER;
|
||||
|
||||
return VEHICLE_ROLE_NONE;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Modify the player view/camera while in a vehicle
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropVehiclePrisonerPod::GetVehicleViewPosition( int nRole, Vector *pAbsOrigin, QAngle *pAbsAngles, float *pFOV /*=NULL*/ )
|
||||
{
|
||||
SharedVehicleViewSmoothing( m_hPlayer,
|
||||
pAbsOrigin, pAbsAngles,
|
||||
m_bEnterAnimOn, m_bExitAnimOn,
|
||||
m_vecEyeExitEndpoint,
|
||||
&m_ViewSmoothingData,
|
||||
pFOV );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pLocalPlayer -
|
||||
// pCmd -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropVehiclePrisonerPod::UpdateViewAngles( C_BasePlayer *pLocalPlayer, CUserCmd *pCmd )
|
||||
{
|
||||
int eyeAttachmentIndex = LookupAttachment( "vehicle_driver_eyes" );
|
||||
Vector vehicleEyeOrigin;
|
||||
QAngle vehicleEyeAngles;
|
||||
GetAttachmentLocal( eyeAttachmentIndex, vehicleEyeOrigin, vehicleEyeAngles );
|
||||
|
||||
// Limit the yaw.
|
||||
float flAngleDiff = AngleDiff( pCmd->viewangles.y, vehicleEyeAngles.y );
|
||||
flAngleDiff = clamp( flAngleDiff, POD_VIEW_YAW_MIN, POD_VIEW_YAW_MAX );
|
||||
pCmd->viewangles.y = vehicleEyeAngles.y + flAngleDiff;
|
||||
|
||||
// Limit the pitch -- don't let them look down into the empty pod!
|
||||
flAngleDiff = AngleDiff( pCmd->viewangles.x, vehicleEyeAngles.x );
|
||||
flAngleDiff = clamp( flAngleDiff, POD_VIEW_PITCH_MIN, POD_VIEW_PITCH_MAX );
|
||||
pCmd->viewangles.x = vehicleEyeAngles.x + flAngleDiff;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Futzes with the clip planes
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropVehiclePrisonerPod::GetVehicleClipPlanes( float &flZNear, float &flZFar ) const
|
||||
{
|
||||
// Pod doesn't need to adjust the clip planes.
|
||||
//flZNear = 6;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Renders hud elements
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_PropVehiclePrisonerPod::DrawHudElements( )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
121
game/client/hl2/c_waterbullet.cpp
Normal file
121
game/client/hl2/c_waterbullet.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "particles_simple.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class C_WaterBullet : public C_BaseAnimating
|
||||
{
|
||||
public:
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_CLASS( C_WaterBullet, C_BaseAnimating );
|
||||
|
||||
C_WaterBullet( void ) {};
|
||||
~C_WaterBullet( void ) {};
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_pEmitter = CSimpleEmitter::Create( "FX_Bubble" );
|
||||
m_pEmitter->SetSortOrigin( GetAbsOrigin() );
|
||||
|
||||
m_vecLastOrigin = GetAbsOrigin();
|
||||
}
|
||||
}
|
||||
|
||||
#define BUBBLES_PER_INCH 0.2
|
||||
|
||||
void AddEntity( void )
|
||||
{
|
||||
Vector direction = GetAbsOrigin() - m_vecLastOrigin;
|
||||
float flDist = VectorNormalize( direction );
|
||||
|
||||
int numBubbles = (int) ( flDist * BUBBLES_PER_INCH );
|
||||
|
||||
if ( numBubbles < 1 )
|
||||
numBubbles = 1;
|
||||
|
||||
// Make bubbles
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
Vector offset;
|
||||
|
||||
for ( int i = 0; i < numBubbles; i++ )
|
||||
{
|
||||
offset = m_vecLastOrigin + ( direction * ( flDist / numBubbles ) * i ) + RandomVector( -2.5f, 2.5f );
|
||||
|
||||
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/bubble" ), offset );
|
||||
|
||||
if ( sParticle )
|
||||
{
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
sParticle->m_flDieTime = random->RandomFloat( 0.75f, 1.25f );
|
||||
|
||||
sParticle->m_flRoll = 0;
|
||||
sParticle->m_flRollDelta = 0;
|
||||
|
||||
unsigned char color = random->RandomInt( 128, 255 );
|
||||
|
||||
sParticle->m_uchColor[0] = color;
|
||||
sParticle->m_uchColor[1] = color;
|
||||
sParticle->m_uchColor[2] = color;
|
||||
sParticle->m_uchStartAlpha = 255;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchStartSize = random->RandomInt( 1, 2 );
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize;
|
||||
|
||||
sParticle->m_vecVelocity = ( direction * 64.0f ) + Vector( 0, 0, 32 );
|
||||
}
|
||||
|
||||
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/splash2" ), offset );
|
||||
|
||||
if ( sParticle )
|
||||
{
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
sParticle->m_flDieTime = 0.2f;
|
||||
|
||||
sParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = random->RandomInt( -4, 4 );
|
||||
|
||||
unsigned char color = random->RandomInt( 200, 255 );
|
||||
|
||||
sParticle->m_uchColor[0] = color;
|
||||
sParticle->m_uchColor[1] = color;
|
||||
sParticle->m_uchColor[2] = color;
|
||||
sParticle->m_uchStartAlpha = 128;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchStartSize = 2;
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4;
|
||||
|
||||
sParticle->m_vecVelocity = ( direction * 64.0f ) + Vector( 0, 0, 32 );
|
||||
}
|
||||
}
|
||||
|
||||
// Save our last position
|
||||
m_vecLastOrigin = GetAbsOrigin();
|
||||
|
||||
BaseClass::AddEntity();
|
||||
}
|
||||
|
||||
bool ShouldDraw( void ) { return true; }
|
||||
|
||||
private:
|
||||
C_WaterBullet( const C_WaterBullet & );
|
||||
|
||||
CSmartPtr<CSimpleEmitter> m_pEmitter;
|
||||
|
||||
Vector m_vecLastOrigin;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_WaterBullet, DT_WaterBullet, CWaterBullet )
|
||||
END_RECV_TABLE()
|
||||
47
game/client/hl2/c_weapon__stubs_hl2.cpp
Normal file
47
game/client/hl2/c_weapon__stubs_hl2.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_weapon__stubs.h"
|
||||
#include "basehlcombatweapon_shared.h"
|
||||
#include "c_basehlcombatweapon.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
STUB_WEAPON_CLASS( cycler_weapon, WeaponCycler, C_BaseCombatWeapon );
|
||||
|
||||
STUB_WEAPON_CLASS( weapon_binoculars, WeaponBinoculars, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_bugbait, WeaponBugBait, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_flaregun, Flaregun, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_annabelle, WeaponAnnabelle, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_gauss, WeaponGaussGun, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_cubemap, WeaponCubemap, C_BaseCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_alyxgun, WeaponAlyxGun, C_HLSelectFireMachineGun );
|
||||
STUB_WEAPON_CLASS( weapon_citizenpackage, WeaponCitizenPackage, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_citizensuitcase, WeaponCitizenSuitcase, C_WeaponCitizenPackage );
|
||||
|
||||
#ifndef HL2MP
|
||||
STUB_WEAPON_CLASS( weapon_ar2, WeaponAR2, C_HLMachineGun );
|
||||
STUB_WEAPON_CLASS( weapon_frag, WeaponFrag, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_rpg, WeaponRPG, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_pistol, WeaponPistol, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_shotgun, WeaponShotgun, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_smg1, WeaponSMG1, C_HLSelectFireMachineGun );
|
||||
STUB_WEAPON_CLASS( weapon_357, Weapon357, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_crossbow, WeaponCrossbow, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_slam, Weapon_SLAM, C_BaseHLCombatWeapon );
|
||||
STUB_WEAPON_CLASS( weapon_crowbar, WeaponCrowbar, C_BaseHLBludgeonWeapon );
|
||||
#ifdef HL2_EPISODIC
|
||||
STUB_WEAPON_CLASS( weapon_hopwire, WeaponHopwire, C_BaseHLCombatWeapon );
|
||||
//STUB_WEAPON_CLASS( weapon_proto1, WeaponProto1, C_BaseHLCombatWeapon );
|
||||
#endif
|
||||
#ifdef HL2_LOSTCOAST
|
||||
STUB_WEAPON_CLASS( weapon_oldmanharpoon, WeaponOldManHarpoon, C_WeaponCitizenPackage );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
159
game/client/hl2/c_weapon_crossbow.cpp
Normal file
159
game/client/hl2/c_weapon_crossbow.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "model_types.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
#include "fx.h"
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#include "beamdraw.h"
|
||||
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectCrossbow )
|
||||
CLIENTEFFECT_MATERIAL( "effects/muzzleflash1" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
//
|
||||
// Crossbow bolt
|
||||
//
|
||||
|
||||
class C_CrossbowBolt : public C_BaseCombatCharacter
|
||||
{
|
||||
DECLARE_CLASS( C_CrossbowBolt, C_BaseCombatCharacter );
|
||||
DECLARE_CLIENTCLASS();
|
||||
public:
|
||||
|
||||
C_CrossbowBolt( void );
|
||||
|
||||
virtual RenderGroup_t GetRenderGroup( void )
|
||||
{
|
||||
// We want to draw translucent bits as well as our main model
|
||||
return RENDER_GROUP_TWOPASS;
|
||||
}
|
||||
|
||||
virtual void ClientThink( void );
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
private:
|
||||
|
||||
C_CrossbowBolt( const C_CrossbowBolt & ); // not defined, not accessible
|
||||
|
||||
Vector m_vecLastOrigin;
|
||||
bool m_bUpdated;
|
||||
};
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_CrossbowBolt, DT_CrossbowBolt, CCrossbowBolt )
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
C_CrossbowBolt::C_CrossbowBolt( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : updateType -
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CrossbowBolt::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
m_bUpdated = false;
|
||||
m_vecLastOrigin = GetAbsOrigin();
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_CrossbowBolt::DrawModel( int flags )
|
||||
{
|
||||
// See if we're drawing the motion blur
|
||||
if ( flags & STUDIO_TRANSPARENCY )
|
||||
{
|
||||
float color[3];
|
||||
IMaterial *pBlurMaterial = materials->FindMaterial( "effects/muzzleflash1", NULL, false );
|
||||
|
||||
Vector vecDir = GetAbsOrigin() - m_vecLastOrigin;
|
||||
float speed = VectorNormalize( vecDir );
|
||||
|
||||
speed = clamp( speed, 0, 32 );
|
||||
|
||||
if ( speed > 0 )
|
||||
{
|
||||
float stepSize = MIN( ( speed * 0.5f ), 4.0f );
|
||||
|
||||
Vector spawnPos = GetAbsOrigin() + ( vecDir * 24.0f );
|
||||
Vector spawnStep = -vecDir * stepSize;
|
||||
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
pRenderContext->Bind( pBlurMaterial );
|
||||
|
||||
float alpha;
|
||||
|
||||
// Draw the motion blurred trail
|
||||
for ( int i = 0; i < 20; i++ )
|
||||
{
|
||||
spawnPos += spawnStep;
|
||||
|
||||
alpha = RemapValClamped( i, 5, 11, 0.25f, 0.05f );
|
||||
|
||||
color[0] = color[1] = color[2] = alpha;
|
||||
|
||||
DrawHalo( pBlurMaterial, spawnPos, 3.0f, color );
|
||||
}
|
||||
}
|
||||
|
||||
if ( gpGlobals->frametime > 0.0f && !m_bUpdated)
|
||||
{
|
||||
m_bUpdated = true;
|
||||
m_vecLastOrigin = GetAbsOrigin();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Draw the normal portion
|
||||
return BaseClass::DrawModel( flags );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_CrossbowBolt::ClientThink( void )
|
||||
{
|
||||
m_bUpdated = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CrosshairLoadCallback( const CEffectData &data )
|
||||
{
|
||||
IClientRenderable *pRenderable = data.GetRenderable( );
|
||||
if ( !pRenderable )
|
||||
return;
|
||||
|
||||
Vector position;
|
||||
QAngle angles;
|
||||
|
||||
// If we found the attachment, emit sparks there
|
||||
if ( pRenderable->GetAttachment( data.m_nAttachmentIndex, position, angles ) )
|
||||
{
|
||||
FX_ElectricSpark( position, 1.0f, 1.0f, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "CrossbowLoad", CrosshairLoadCallback );
|
||||
166
game/client/hl2/c_weapon_gravitygun.cpp
Normal file
166
game/client/hl2/c_weapon_gravitygun.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//===========================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "in_buttons.h"
|
||||
#include "beamdraw.h"
|
||||
#include "c_weapon__stubs.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectGravityGun )
|
||||
CLIENTEFFECT_MATERIAL( "sprites/physbeam" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
class C_BeamQuadratic : public CDefaultClientRenderable
|
||||
{
|
||||
public:
|
||||
C_BeamQuadratic();
|
||||
void Update( C_BaseEntity *pOwner );
|
||||
|
||||
// IClientRenderable
|
||||
virtual const Vector& GetRenderOrigin( void ) { return m_worldPosition; }
|
||||
virtual const QAngle& GetRenderAngles( void ) { return vec3_angle; }
|
||||
virtual bool ShouldDraw( void ) { return true; }
|
||||
virtual bool IsTransparent( void ) { return true; }
|
||||
virtual bool ShouldReceiveProjectedTextures( int flags ) { return false; }
|
||||
virtual int DrawModel( int flags );
|
||||
|
||||
// Returns the bounds relative to the origin (render bounds)
|
||||
virtual void GetRenderBounds( Vector& mins, Vector& maxs )
|
||||
{
|
||||
// bogus. But it should draw if you can see the end point
|
||||
mins.Init(-32,-32,-32);
|
||||
maxs.Init(32,32,32);
|
||||
}
|
||||
|
||||
C_BaseEntity *m_pOwner;
|
||||
Vector m_targetPosition;
|
||||
Vector m_worldPosition;
|
||||
int m_active;
|
||||
int m_glueTouching;
|
||||
int m_viewModelIndex;
|
||||
};
|
||||
|
||||
|
||||
class C_WeaponGravityGun : public C_BaseCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( C_WeaponGravityGun, C_BaseCombatWeapon );
|
||||
public:
|
||||
C_WeaponGravityGun() {}
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
int KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding )
|
||||
{
|
||||
if ( gHUD.m_iKeyBits & IN_ATTACK )
|
||||
{
|
||||
switch ( keynum )
|
||||
{
|
||||
case MOUSE_WHEEL_UP:
|
||||
gHUD.m_iKeyBits |= IN_WEAPON1;
|
||||
return 0;
|
||||
|
||||
case MOUSE_WHEEL_DOWN:
|
||||
gHUD.m_iKeyBits |= IN_WEAPON2;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow engine to process
|
||||
return BaseClass::KeyInput( down, keynum, pszCurrentBinding );
|
||||
}
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
m_beam.Update( this );
|
||||
}
|
||||
|
||||
private:
|
||||
C_WeaponGravityGun( const C_WeaponGravityGun & );
|
||||
|
||||
C_BeamQuadratic m_beam;
|
||||
};
|
||||
|
||||
STUB_WEAPON_CLASS_IMPLEMENT( weapon_physgun, C_WeaponGravityGun );
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_WeaponGravityGun, DT_WeaponGravityGun, CWeaponGravityGun )
|
||||
RecvPropVector( RECVINFO_NAME(m_beam.m_targetPosition,m_targetPosition) ),
|
||||
RecvPropVector( RECVINFO_NAME(m_beam.m_worldPosition, m_worldPosition) ),
|
||||
RecvPropInt( RECVINFO_NAME(m_beam.m_active, m_active) ),
|
||||
RecvPropInt( RECVINFO_NAME(m_beam.m_glueTouching, m_glueTouching) ),
|
||||
RecvPropInt( RECVINFO_NAME(m_beam.m_viewModelIndex, m_viewModelIndex) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
|
||||
C_BeamQuadratic::C_BeamQuadratic()
|
||||
{
|
||||
m_pOwner = NULL;
|
||||
}
|
||||
|
||||
void C_BeamQuadratic::Update( C_BaseEntity *pOwner )
|
||||
{
|
||||
m_pOwner = pOwner;
|
||||
if ( m_active )
|
||||
{
|
||||
if ( m_hRenderHandle == INVALID_CLIENT_RENDER_HANDLE )
|
||||
{
|
||||
ClientLeafSystem()->AddRenderable( this, RENDER_GROUP_TRANSLUCENT_ENTITY );
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientLeafSystem()->RenderableChanged( m_hRenderHandle );
|
||||
}
|
||||
}
|
||||
else if ( !m_active && m_hRenderHandle != INVALID_CLIENT_RENDER_HANDLE )
|
||||
{
|
||||
ClientLeafSystem()->RemoveRenderable( m_hRenderHandle );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int C_BeamQuadratic::DrawModel( int )
|
||||
{
|
||||
Vector points[3];
|
||||
QAngle tmpAngle;
|
||||
|
||||
if ( !m_active )
|
||||
return 0;
|
||||
|
||||
C_BaseEntity *pEnt = cl_entitylist->GetEnt( m_viewModelIndex );
|
||||
if ( !pEnt )
|
||||
return 0;
|
||||
pEnt->GetAttachment( 1, points[0], tmpAngle );
|
||||
|
||||
points[1] = 0.5 * (m_targetPosition + points[0]);
|
||||
|
||||
// a little noise 11t & 13t should be somewhat non-periodic looking
|
||||
//points[1].z += 4*sin( gpGlobals->curtime*11 ) + 5*cos( gpGlobals->curtime*13 );
|
||||
points[2] = m_worldPosition;
|
||||
|
||||
IMaterial *pMat = materials->FindMaterial( "sprites/physbeam", TEXTURE_GROUP_CLIENT_EFFECTS );
|
||||
Vector color;
|
||||
if ( m_glueTouching )
|
||||
{
|
||||
color.Init(1,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
color.Init(1,1,1);
|
||||
}
|
||||
|
||||
float scrollOffset = gpGlobals->curtime - (int)gpGlobals->curtime;
|
||||
materials->Bind( pMat );
|
||||
DrawBeamQuadratic( points[0], points[1], points[2], 13, color, scrollOffset );
|
||||
return 1;
|
||||
}
|
||||
|
||||
442
game/client/hl2/c_weapon_physcannon.cpp
Normal file
442
game/client/hl2/c_weapon_physcannon.cpp
Normal file
@@ -0,0 +1,442 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "c_weapon__stubs.h"
|
||||
#include "c_basehlcombatweapon.h"
|
||||
#include "fx.h"
|
||||
#include "particles_localspace.h"
|
||||
#include "view.h"
|
||||
#include "particles_attractor.h"
|
||||
|
||||
class C_WeaponPhysCannon: public C_BaseHLCombatWeapon
|
||||
{
|
||||
DECLARE_CLASS( C_WeaponPhysCannon, C_BaseHLCombatWeapon );
|
||||
public:
|
||||
C_WeaponPhysCannon( void );
|
||||
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
virtual void OnDataChanged( DataUpdateType_t updateType );
|
||||
virtual int DrawModel( int flags );
|
||||
virtual void ClientThink( void );
|
||||
|
||||
virtual bool ShouldUseLargeViewModelVROverride() OVERRIDE { return true; }
|
||||
|
||||
private:
|
||||
|
||||
bool SetupEmitter( void );
|
||||
|
||||
bool m_bIsCurrentlyUpgrading;
|
||||
float m_flTimeForceView;
|
||||
float m_flTimeIgnoreForceView;
|
||||
bool m_bWasUpgraded;
|
||||
|
||||
CSmartPtr<CLocalSpaceEmitter> m_pLocalEmitter;
|
||||
CSmartPtr<CSimpleEmitter> m_pEmitter;
|
||||
CSmartPtr<CParticleAttractor> m_pAttractor;
|
||||
};
|
||||
|
||||
STUB_WEAPON_CLASS_IMPLEMENT( weapon_physcannon, C_WeaponPhysCannon );
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_WeaponPhysCannon, DT_WeaponPhysCannon, CWeaponPhysCannon )
|
||||
RecvPropBool( RECVINFO( m_bIsCurrentlyUpgrading ) ),
|
||||
RecvPropFloat( RECVINFO( m_flTimeForceView) ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
C_WeaponPhysCannon::C_WeaponPhysCannon( void )
|
||||
{
|
||||
m_bWasUpgraded = false;
|
||||
m_flTimeIgnoreForceView = -1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void C_WeaponPhysCannon::OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool C_WeaponPhysCannon::SetupEmitter( void )
|
||||
{
|
||||
if ( !m_pLocalEmitter.IsValid() )
|
||||
{
|
||||
m_pLocalEmitter = CLocalSpaceEmitter::Create( "physpowerup", GetRefEHandle(), LookupAttachment( "core" ) );
|
||||
|
||||
if ( m_pLocalEmitter.IsValid() == false )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !m_pAttractor.IsValid() )
|
||||
{
|
||||
m_pAttractor = CParticleAttractor::Create( vec3_origin, "physpowerup_att" );
|
||||
|
||||
if ( m_pAttractor.IsValid() == false )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !m_pEmitter.IsValid() )
|
||||
{
|
||||
m_pEmitter = CSimpleEmitter::Create( "physpowerup_glow" );
|
||||
|
||||
if ( m_pEmitter.IsValid() == false )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Sorts the components of a vector
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline void SortAbsVectorComponents( const Vector& src, int* pVecIdx )
|
||||
{
|
||||
Vector absVec( fabs(src[0]), fabs(src[1]), fabs(src[2]) );
|
||||
|
||||
int maxIdx = (absVec[0] > absVec[1]) ? 0 : 1;
|
||||
if (absVec[2] > absVec[maxIdx])
|
||||
{
|
||||
maxIdx = 2;
|
||||
}
|
||||
|
||||
// always choose something right-handed....
|
||||
switch( maxIdx )
|
||||
{
|
||||
case 0:
|
||||
pVecIdx[0] = 1;
|
||||
pVecIdx[1] = 2;
|
||||
pVecIdx[2] = 0;
|
||||
break;
|
||||
case 1:
|
||||
pVecIdx[0] = 2;
|
||||
pVecIdx[1] = 0;
|
||||
pVecIdx[2] = 1;
|
||||
break;
|
||||
case 2:
|
||||
pVecIdx[0] = 0;
|
||||
pVecIdx[1] = 1;
|
||||
pVecIdx[2] = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compute the bounding box's center, size, and basis
|
||||
//-----------------------------------------------------------------------------
|
||||
void ComputeRenderInfo( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld,
|
||||
Vector *pVecAbsOrigin, Vector *pXVec, Vector *pYVec )
|
||||
{
|
||||
// Compute the center of the hitbox in worldspace
|
||||
Vector vecHitboxCenter;
|
||||
VectorAdd( pHitBox->bbmin, pHitBox->bbmax, vecHitboxCenter );
|
||||
vecHitboxCenter *= 0.5f;
|
||||
VectorTransform( vecHitboxCenter, hitboxToWorld, *pVecAbsOrigin );
|
||||
|
||||
// Get the object's basis
|
||||
Vector vec[3];
|
||||
MatrixGetColumn( hitboxToWorld, 0, vec[0] );
|
||||
MatrixGetColumn( hitboxToWorld, 1, vec[1] );
|
||||
MatrixGetColumn( hitboxToWorld, 2, vec[2] );
|
||||
// vec[1] *= -1.0f;
|
||||
|
||||
Vector vecViewDir;
|
||||
VectorSubtract( CurrentViewOrigin(), *pVecAbsOrigin, vecViewDir );
|
||||
VectorNormalize( vecViewDir );
|
||||
|
||||
// Project the shadow casting direction into the space of the hitbox
|
||||
Vector localViewDir;
|
||||
localViewDir[0] = DotProduct( vec[0], vecViewDir );
|
||||
localViewDir[1] = DotProduct( vec[1], vecViewDir );
|
||||
localViewDir[2] = DotProduct( vec[2], vecViewDir );
|
||||
|
||||
// Figure out which vector has the largest component perpendicular
|
||||
// to the view direction...
|
||||
// Sort by how perpendicular it is
|
||||
int vecIdx[3];
|
||||
SortAbsVectorComponents( localViewDir, vecIdx );
|
||||
|
||||
// Here's our hitbox basis vectors; namely the ones that are
|
||||
// most perpendicular to the view direction
|
||||
*pXVec = vec[vecIdx[0]];
|
||||
*pYVec = vec[vecIdx[1]];
|
||||
|
||||
// Project them into a plane perpendicular to the view direction
|
||||
*pXVec -= vecViewDir * DotProduct( vecViewDir, *pXVec );
|
||||
*pYVec -= vecViewDir * DotProduct( vecViewDir, *pYVec );
|
||||
VectorNormalize( *pXVec );
|
||||
VectorNormalize( *pYVec );
|
||||
|
||||
// Compute the hitbox size
|
||||
Vector boxSize;
|
||||
VectorSubtract( pHitBox->bbmax, pHitBox->bbmin, boxSize );
|
||||
|
||||
// We project the two longest sides into the vectors perpendicular
|
||||
// to the projection direction, then add in the projection of the perp direction
|
||||
Vector2D size( boxSize[vecIdx[0]], boxSize[vecIdx[1]] );
|
||||
size.x *= fabs( DotProduct( vec[vecIdx[0]], *pXVec ) );
|
||||
size.y *= fabs( DotProduct( vec[vecIdx[1]], *pYVec ) );
|
||||
|
||||
// Add the third component into x and y
|
||||
size.x += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pXVec ) );
|
||||
size.y += boxSize[vecIdx[2]] * fabs( DotProduct( vec[vecIdx[2]], *pYVec ) );
|
||||
|
||||
// Bloat a bit, since the shadow wants to extend outside the model a bit
|
||||
size *= 2.0f;
|
||||
|
||||
// Clamp the minimum size
|
||||
Vector2DMax( size, Vector2D(10.0f, 10.0f), size );
|
||||
|
||||
// Factor the size into the xvec + yvec
|
||||
(*pXVec) *= size.x * 0.5f;
|
||||
(*pYVec) *= size.y * 0.5f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : flags -
|
||||
// Output : int
|
||||
//-----------------------------------------------------------------------------
|
||||
int C_WeaponPhysCannon::DrawModel( int flags )
|
||||
{
|
||||
// If we're not ugrading, don't do anything special
|
||||
if ( m_bIsCurrentlyUpgrading == false && m_bWasUpgraded == false )
|
||||
return BaseClass::DrawModel( flags );
|
||||
|
||||
if ( gpGlobals->frametime == 0 )
|
||||
return BaseClass::DrawModel( flags );
|
||||
|
||||
if ( !m_bReadyToDraw )
|
||||
return 0;
|
||||
|
||||
m_bWasUpgraded = true;
|
||||
|
||||
// Create the particle emitter if it's not already
|
||||
if ( SetupEmitter() )
|
||||
{
|
||||
// Add the power-up particles
|
||||
|
||||
// See if we should draw
|
||||
if ( m_bReadyToDraw == false )
|
||||
return 0;
|
||||
|
||||
C_BaseAnimating *pAnimating = GetBaseAnimating();
|
||||
if (!pAnimating)
|
||||
return 0;
|
||||
|
||||
matrix3x4_t *hitboxbones[MAXSTUDIOBONES];
|
||||
if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) )
|
||||
return 0;
|
||||
|
||||
studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() );
|
||||
if (!pStudioHdr)
|
||||
return false;
|
||||
|
||||
mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() );
|
||||
if ( !set )
|
||||
return false;
|
||||
|
||||
int i;
|
||||
|
||||
float fadePerc = 1.0f;
|
||||
|
||||
if ( m_bIsCurrentlyUpgrading )
|
||||
{
|
||||
Vector vecSkew = vec3_origin;
|
||||
|
||||
// Skew the particles in front or in back of their targets
|
||||
vecSkew = CurrentViewForward() * 4.0f;
|
||||
|
||||
float spriteScale = 1.0f;
|
||||
spriteScale = clamp( spriteScale, 0.75f, 1.0f );
|
||||
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
for ( i = 0; i < set->numhitboxes; ++i )
|
||||
{
|
||||
Vector vecAbsOrigin, xvec, yvec;
|
||||
mstudiobbox_t *pBox = set->pHitbox(i);
|
||||
ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec );
|
||||
|
||||
Vector offset;
|
||||
Vector xDir, yDir;
|
||||
|
||||
xDir = xvec;
|
||||
float xScale = VectorNormalize( xDir ) * 0.75f;
|
||||
|
||||
yDir = yvec;
|
||||
float yScale = VectorNormalize( yDir ) * 0.75f;
|
||||
|
||||
int numParticles = clamp( 4.0f * fadePerc, 1, 3 );
|
||||
|
||||
for ( int j = 0; j < numParticles; j++ )
|
||||
{
|
||||
offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f );
|
||||
offset += vecSkew;
|
||||
|
||||
sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/combinemuzzle1" ), vecAbsOrigin + offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return 1;
|
||||
|
||||
sParticle->m_vecVelocity = vec3_origin;
|
||||
sParticle->m_uchStartSize = 16.0f * spriteScale;
|
||||
sParticle->m_flDieTime = 0.2f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f );
|
||||
|
||||
float alpha = 40;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int attachment = LookupAttachment( "core" );
|
||||
Vector coreOrigin;
|
||||
QAngle coreAngles;
|
||||
|
||||
GetAttachment( attachment, coreOrigin, coreAngles );
|
||||
|
||||
SimpleParticle *sParticle;
|
||||
|
||||
// Do the core effects
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
sParticle = (SimpleParticle *) m_pLocalEmitter->AddParticle( sizeof(SimpleParticle), m_pLocalEmitter->GetPMaterial( "effects/strider_muzzle" ), vec3_origin );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return 1;
|
||||
|
||||
sParticle->m_vecVelocity = vec3_origin;
|
||||
sParticle->m_flDieTime = 0.1f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 255;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
if ( i < 2 )
|
||||
{
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1);
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( random->RandomInt( 0, 20 ) == 0 )
|
||||
{
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1);
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4.0f;
|
||||
sParticle->m_flDieTime = 0.25f;
|
||||
}
|
||||
else
|
||||
{
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1);
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_bWasUpgraded && m_bIsCurrentlyUpgrading )
|
||||
{
|
||||
// Update our attractor point
|
||||
m_pAttractor->SetAttractorOrigin( coreOrigin );
|
||||
|
||||
Vector offset;
|
||||
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
offset = coreOrigin + RandomVector( -32.0f, 32.0f );
|
||||
|
||||
sParticle = (SimpleParticle *) m_pAttractor->AddParticle( sizeof(SimpleParticle), m_pAttractor->GetPMaterial( "effects/strider_muzzle" ), offset );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return 1;
|
||||
|
||||
sParticle->m_vecVelocity = Vector(0,0,8);
|
||||
sParticle->m_flDieTime = 0.5f;
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
|
||||
sParticle->m_flRoll = Helper_RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
float alpha = 255;
|
||||
|
||||
sParticle->m_uchColor[0] = alpha;
|
||||
sParticle->m_uchColor[1] = alpha;
|
||||
sParticle->m_uchColor[2] = alpha;
|
||||
sParticle->m_uchStartAlpha = alpha;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
|
||||
sParticle->m_uchStartSize = random->RandomFloat( 1, 2 );
|
||||
sParticle->m_uchEndSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return BaseClass::DrawModel( flags );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// On 360, raise up the player's view if the server has
|
||||
// asked us to.
|
||||
//---------------------------------------------------------
|
||||
#define PHYSCANNON_RAISE_VIEW_GOAL 0.0f
|
||||
void C_WeaponPhysCannon::ClientThink( void )
|
||||
{
|
||||
if( m_flTimeIgnoreForceView > gpGlobals->curtime )
|
||||
return;
|
||||
|
||||
float flTime = (m_flTimeForceView - gpGlobals->curtime);
|
||||
|
||||
if( flTime < 0.0f )
|
||||
return;
|
||||
|
||||
float flDT = 1.0f - flTime;
|
||||
if( flDT > 0.0f )
|
||||
{
|
||||
QAngle viewangles;
|
||||
engine->GetViewAngles( viewangles );
|
||||
|
||||
if( viewangles.x > PHYSCANNON_RAISE_VIEW_GOAL + 1.0f )
|
||||
{
|
||||
float flDelta = PHYSCANNON_RAISE_VIEW_GOAL - viewangles.x;
|
||||
viewangles.x += (flDelta * flDT);
|
||||
engine->SetViewAngles(viewangles);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We've reached our goal. Ignore the forced view angles for now.
|
||||
m_flTimeIgnoreForceView = m_flTimeForceView + 0.1f;
|
||||
}
|
||||
}
|
||||
|
||||
return BaseClass::ClientThink();
|
||||
}
|
||||
|
||||
|
||||
187
game/client/hl2/c_weapon_stunstick.cpp
Normal file
187
game/client/hl2/c_weapon_stunstick.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_basehlcombatweapon.h"
|
||||
#include "iviewrender_beams.h"
|
||||
#include "beam_shared.h"
|
||||
#include "c_weapon__stubs.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
#include "beamdraw.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheEffectStunstick )
|
||||
CLIENTEFFECT_MATERIAL( "effects/stunstick" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
class C_WeaponStunStick : public C_BaseHLBludgeonWeapon
|
||||
{
|
||||
DECLARE_CLASS( C_WeaponStunStick, C_BaseHLBludgeonWeapon );
|
||||
public:
|
||||
DECLARE_CLIENTCLASS();
|
||||
DECLARE_PREDICTABLE();
|
||||
|
||||
int DrawModel( int flags )
|
||||
{
|
||||
//FIXME: This sucks, but I can't easily create temp ents...
|
||||
|
||||
if ( m_bActive )
|
||||
{
|
||||
Vector vecOrigin;
|
||||
QAngle vecAngles;
|
||||
float color[3];
|
||||
|
||||
color[0] = color[1] = color[2] = random->RandomFloat( 0.1f, 0.2f );
|
||||
|
||||
GetAttachment( 1, vecOrigin, vecAngles );
|
||||
|
||||
Vector vForward;
|
||||
AngleVectors( vecAngles, &vForward );
|
||||
|
||||
Vector vEnd = vecOrigin - vForward * 1.0f;
|
||||
|
||||
IMaterial *pMaterial = materials->FindMaterial( "effects/stunstick", NULL, false );
|
||||
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
pRenderContext->Bind( pMaterial );
|
||||
DrawHalo( pMaterial, vEnd, random->RandomFloat( 4.0f, 6.0f ), color );
|
||||
|
||||
color[0] = color[1] = color[2] = random->RandomFloat( 0.9f, 1.0f );
|
||||
|
||||
DrawHalo( pMaterial, vEnd, random->RandomFloat( 2.0f, 3.0f ), color );
|
||||
}
|
||||
|
||||
return BaseClass::DrawModel( flags );
|
||||
}
|
||||
|
||||
// Do part of our effect
|
||||
void ClientThink( void )
|
||||
{
|
||||
// Update our effects
|
||||
if ( m_bActive &&
|
||||
gpGlobals->frametime != 0.0f &&
|
||||
( random->RandomInt( 0, 5 ) == 0 ) )
|
||||
{
|
||||
Vector vecOrigin;
|
||||
QAngle vecAngles;
|
||||
|
||||
GetAttachment( 1, vecOrigin, vecAngles );
|
||||
|
||||
Vector vForward;
|
||||
AngleVectors( vecAngles, &vForward );
|
||||
|
||||
Vector vEnd = vecOrigin - vForward * 1.0f;
|
||||
|
||||
// Inner beams
|
||||
BeamInfo_t beamInfo;
|
||||
|
||||
beamInfo.m_vecStart = vEnd;
|
||||
Vector offset = RandomVector( -6, 2 );
|
||||
|
||||
offset += Vector(2,2,2);
|
||||
beamInfo.m_vecEnd = vecOrigin + offset;
|
||||
|
||||
beamInfo.m_pStartEnt= cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
|
||||
beamInfo.m_pEndEnt = cl_entitylist->GetEnt( BEAMENT_ENTITY( entindex() ) );
|
||||
beamInfo.m_nStartAttachment = 1;
|
||||
beamInfo.m_nEndAttachment = 2;
|
||||
|
||||
beamInfo.m_nType = TE_BEAMTESLA;
|
||||
beamInfo.m_pszModelName = "sprites/physbeam.vmt";
|
||||
beamInfo.m_flHaloScale = 0.0f;
|
||||
beamInfo.m_flLife = 0.01f;
|
||||
beamInfo.m_flWidth = random->RandomFloat( 0.5f, 2.0f );
|
||||
beamInfo.m_flEndWidth = 0;
|
||||
beamInfo.m_flFadeLength = 0.0f;
|
||||
beamInfo.m_flAmplitude = random->RandomFloat( 1, 2 );
|
||||
beamInfo.m_flBrightness = 255.0;
|
||||
beamInfo.m_flSpeed = 0.0;
|
||||
beamInfo.m_nStartFrame = 0.0;
|
||||
beamInfo.m_flFrameRate = 1.0f;
|
||||
beamInfo.m_flRed = 255.0f;;
|
||||
beamInfo.m_flGreen = 255.0f;
|
||||
beamInfo.m_flBlue = 255.0f;
|
||||
beamInfo.m_nSegments = 8;
|
||||
beamInfo.m_bRenderable = true;
|
||||
beamInfo.m_nFlags = (FBEAM_ONLYNOISEONCE|FBEAM_SHADEOUT);
|
||||
|
||||
beams->CreateBeamPoints( beamInfo );
|
||||
}
|
||||
}
|
||||
|
||||
void OnDataChanged( DataUpdateType_t updateType )
|
||||
{
|
||||
BaseClass::OnDataChanged( updateType );
|
||||
if ( updateType == DATA_UPDATE_CREATED )
|
||||
{
|
||||
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void StartStunEffect( void )
|
||||
{
|
||||
//TODO: Play startup sound
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void StopStunEffect( void )
|
||||
{
|
||||
//TODO: Play shutdown sound
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : RenderGroup_t
|
||||
//-----------------------------------------------------------------------------
|
||||
RenderGroup_t GetRenderGroup( void )
|
||||
{
|
||||
return RENDER_GROUP_TRANSLUCENT_ENTITY;
|
||||
}
|
||||
|
||||
private:
|
||||
CNetworkVar( bool, m_bActive );
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pData -
|
||||
// *pStruct -
|
||||
// *pOut -
|
||||
//-----------------------------------------------------------------------------
|
||||
void RecvProxy_StunActive( const CRecvProxyData *pData, void *pStruct, void *pOut )
|
||||
{
|
||||
bool state = *((bool *)&pData->m_Value.m_Int);
|
||||
|
||||
C_WeaponStunStick *pWeapon = (C_WeaponStunStick *) pStruct;
|
||||
|
||||
if ( state )
|
||||
{
|
||||
// Turn on the effect
|
||||
pWeapon->StartStunEffect();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Turn off the effect
|
||||
pWeapon->StopStunEffect();
|
||||
}
|
||||
|
||||
*(bool *)pOut = state;
|
||||
}
|
||||
|
||||
STUB_WEAPON_CLASS_IMPLEMENT( weapon_stunstick, C_WeaponStunStick );
|
||||
|
||||
IMPLEMENT_CLIENTCLASS_DT( C_WeaponStunStick, DT_WeaponStunStick, CWeaponStunStick )
|
||||
RecvPropInt( RECVINFO(m_bActive), 0, RecvProxy_StunActive ),
|
||||
END_RECV_TABLE()
|
||||
|
||||
99
game/client/hl2/clientmode_hlnormal.cpp
Normal file
99
game/client/hl2/clientmode_hlnormal.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Draws the normal TF2 or HL2 HUD.
|
||||
//
|
||||
//=============================================================================
|
||||
#include "cbase.h"
|
||||
#include "clientmode_hlnormal.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 "ienginevgui.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern bool g_bRollingCredits;
|
||||
|
||||
ConVar fov_desired( "fov_desired", "75", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 90.0 );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Globals
|
||||
//-----------------------------------------------------------------------------
|
||||
vgui::HScheme g_hVGuiCombineScheme = 0;
|
||||
|
||||
|
||||
// Instance the singleton and expose the interface to it.
|
||||
IClientMode *GetClientModeNormal()
|
||||
{
|
||||
static ClientModeHLNormal g_ClientModeNormal;
|
||||
return &g_ClientModeNormal;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 void CreateDefaultPanels( void ) { /* don't create any panels yet*/ };
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ClientModeHLNormal implementation
|
||||
//-----------------------------------------------------------------------------
|
||||
ClientModeHLNormal::ClientModeHLNormal()
|
||||
{
|
||||
m_pViewport = new CHudViewport();
|
||||
m_pViewport->Start( gameuifuncs, gameeventmanager );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
ClientModeHLNormal::~ClientModeHLNormal()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ClientModeHLNormal::Init()
|
||||
{
|
||||
BaseClass::Init();
|
||||
|
||||
// Load up the combine control panel scheme
|
||||
g_hVGuiCombineScheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), IsXbox() ? "resource/ClientScheme.res" : "resource/CombinePanelScheme.res", "CombineScheme" );
|
||||
if (!g_hVGuiCombineScheme)
|
||||
{
|
||||
Warning( "Couldn't load combine panel scheme!\n" );
|
||||
}
|
||||
}
|
||||
|
||||
bool ClientModeHLNormal::ShouldDrawCrosshair( void )
|
||||
{
|
||||
return ( g_bRollingCredits == false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
45
game/client/hl2/clientmode_hlnormal.h
Normal file
45
game/client/hl2/clientmode_hlnormal.h
Normal file
@@ -0,0 +1,45 @@
|
||||
//========= 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 ClientModeHLNormal : public ClientModeShared
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS( ClientModeHLNormal, ClientModeShared );
|
||||
|
||||
ClientModeHLNormal();
|
||||
~ClientModeHLNormal();
|
||||
|
||||
virtual void Init();
|
||||
virtual bool ShouldDrawCrosshair( void );
|
||||
};
|
||||
|
||||
extern IClientMode *GetClientModeNormal();
|
||||
extern vgui::HScheme g_hVGuiCombineScheme;
|
||||
|
||||
#endif // CLIENTMODE_HLNORMAL_H
|
||||
334
game/client/hl2/fx_antlion.cpp
Normal file
334
game/client/hl2/fx_antlion.cpp
Normal file
@@ -0,0 +1,334 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "fx.h"
|
||||
#include "c_gib.h"
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#include "iefx.h"
|
||||
#include "decals.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
PMaterialHandle g_Material_Blood[2] = { NULL, NULL };
|
||||
|
||||
#ifdef _XBOX
|
||||
|
||||
// XBox only uses a few gibs
|
||||
#define NUM_ANTLION_GIBS 3
|
||||
const char *pszAntlionGibs[NUM_ANTLION_GIBS] = {
|
||||
"models/gibs/antlion_gib_large_2.mdl", // Head
|
||||
"models/gibs/antlion_gib_medium_1.mdl", // Pincher
|
||||
"models/gibs/antlion_gib_medium_2.mdl", // Leg
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// Use all the gibs
|
||||
#define NUM_ANTLION_GIBS_UNIQUE 3
|
||||
const char *pszAntlionGibs_Unique[NUM_ANTLION_GIBS_UNIQUE] = {
|
||||
"models/gibs/antlion_gib_large_1.mdl",
|
||||
"models/gibs/antlion_gib_large_2.mdl",
|
||||
"models/gibs/antlion_gib_large_3.mdl"
|
||||
};
|
||||
|
||||
#define NUM_ANTLION_GIBS_MEDIUM 3
|
||||
const char *pszAntlionGibs_Medium[NUM_ANTLION_GIBS_MEDIUM] = {
|
||||
"models/gibs/antlion_gib_medium_1.mdl",
|
||||
"models/gibs/antlion_gib_medium_2.mdl",
|
||||
"models/gibs/antlion_gib_medium_3.mdl"
|
||||
};
|
||||
|
||||
// XBox doesn't use the smaller gibs, so don't cache them
|
||||
#define NUM_ANTLION_GIBS_SMALL 3
|
||||
const char *pszAntlionGibs_Small[NUM_ANTLION_GIBS_SMALL] = {
|
||||
"models/gibs/antlion_gib_small_1.mdl",
|
||||
"models/gibs/antlion_gib_small_2.mdl",
|
||||
"models/gibs/antlion_gib_small_3.mdl"
|
||||
};
|
||||
#endif
|
||||
|
||||
ConVar g_antlion_maxgibs( "g_antlion_maxgibs", "16", FCVAR_ARCHIVE );
|
||||
|
||||
void CAntlionGibManager::LevelInitPreEntity( void )
|
||||
{
|
||||
m_LRU.Purge();
|
||||
}
|
||||
|
||||
CAntlionGibManager s_AntlionGibManager( "CAntlionGibManager" );
|
||||
|
||||
void CAntlionGibManager::AddGib( C_BaseEntity *pEntity )
|
||||
{
|
||||
m_LRU.AddToTail( pEntity );
|
||||
}
|
||||
|
||||
void CAntlionGibManager::RemoveGib( C_BaseEntity *pEntity )
|
||||
{
|
||||
m_LRU.FindAndRemove( pEntity );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Methods of IGameSystem
|
||||
//-----------------------------------------------------------------------------
|
||||
void CAntlionGibManager::Update( float frametime )
|
||||
{
|
||||
if ( m_LRU.Count() < g_antlion_maxgibs.GetInt() )
|
||||
return;
|
||||
|
||||
int i = 0;
|
||||
i = m_LRU.Head();
|
||||
|
||||
if ( m_LRU[ i ].Get() )
|
||||
{
|
||||
m_LRU[ i ].Get()->SetNextClientThink( gpGlobals->curtime );
|
||||
}
|
||||
|
||||
m_LRU.Remove(i);
|
||||
}
|
||||
|
||||
// Antlion gib - marks surfaces when it bounces
|
||||
|
||||
class C_AntlionGib : public C_Gib
|
||||
{
|
||||
typedef C_Gib BaseClass;
|
||||
public:
|
||||
|
||||
static C_AntlionGib *CreateClientsideGib( const char *pszModelName, Vector vecOrigin, Vector vecForceDir, AngularImpulse vecAngularImp, float m_flLifetime = DEFAULT_GIB_LIFETIME )
|
||||
{
|
||||
C_AntlionGib *pGib = new C_AntlionGib;
|
||||
|
||||
if ( pGib == NULL )
|
||||
return NULL;
|
||||
|
||||
if ( pGib->InitializeGib( pszModelName, vecOrigin, vecForceDir, vecAngularImp, m_flLifetime ) == false )
|
||||
return NULL;
|
||||
|
||||
s_AntlionGibManager.AddGib( pGib );
|
||||
|
||||
return pGib;
|
||||
}
|
||||
|
||||
// Decal the surface
|
||||
virtual void HitSurface( C_BaseEntity *pOther )
|
||||
{
|
||||
//JDW: Removed for the time being
|
||||
|
||||
/*
|
||||
int index = decalsystem->GetDecalIndexForName( "YellowBlood" );
|
||||
|
||||
if (index >= 0 )
|
||||
{
|
||||
effects->DecalShoot( index, pOther->entindex(), pOther->GetModel(), pOther->GetAbsOrigin(), pOther->GetAbsAngles(), GetAbsOrigin(), 0, 0 );
|
||||
}
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &origin -
|
||||
//-----------------------------------------------------------------------------
|
||||
void FX_AntlionGib( const Vector &origin, const Vector &direction, float scale )
|
||||
{
|
||||
Vector offset;
|
||||
|
||||
#ifdef _XBOX
|
||||
|
||||
// Throw less gibs for XBox
|
||||
for ( int i = 0; i < NUM_ANTLION_GIBS; i++ )
|
||||
{
|
||||
offset = RandomVector( -32, 32 ) + origin;
|
||||
C_AntlionGib::CreateClientsideGib( pszAntlionGibs[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 250 * scale ), RandomAngularImpulse( -32, 32 ), 1.0f );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_UNIQUE );
|
||||
|
||||
// Spawn all the unique gibs
|
||||
for ( int i = 0; i < numGibs; i++ )
|
||||
{
|
||||
offset = RandomVector( -16, 16 ) + origin;
|
||||
|
||||
C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Unique[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 150 * scale ), RandomAngularImpulse( -32, 32 ), 2.0f);
|
||||
}
|
||||
|
||||
numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_MEDIUM );
|
||||
|
||||
// Spawn all the medium gibs
|
||||
for ( int i = 0; i < numGibs; i++ )
|
||||
{
|
||||
offset = RandomVector( -16, 16 ) + origin;
|
||||
|
||||
C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Medium[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 250 * scale ), RandomAngularImpulse( -200, 200 ), 1.0f );
|
||||
}
|
||||
|
||||
numGibs = random->RandomInt( 1, NUM_ANTLION_GIBS_SMALL );
|
||||
|
||||
// Spawn all the small gibs
|
||||
for ( int i = 0; i < NUM_ANTLION_GIBS_SMALL; i++ )
|
||||
{
|
||||
offset = RandomVector( -16, 16 ) + origin;
|
||||
|
||||
C_AntlionGib::CreateClientsideGib( pszAntlionGibs_Small[i], offset, ( direction + RandomVector( -0.8f, 0.8f ) ) * ( 400 * scale ), RandomAngularImpulse( -300, 300 ), 0.5f );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _XBOX
|
||||
|
||||
//
|
||||
// Throw some blood
|
||||
//
|
||||
|
||||
CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "FX_AntlionGib" );
|
||||
pSimple->SetSortOrigin( origin );
|
||||
pSimple->GetBinding().SetBBox( origin - Vector(64,64,64), origin + Vector(64,64,64) );
|
||||
|
||||
// Cache this if we're not already
|
||||
if ( g_Material_Blood[0] == NULL )
|
||||
{
|
||||
g_Material_Blood[0] = g_Mat_BloodPuff[0];
|
||||
}
|
||||
|
||||
if ( g_Material_Blood[1] == NULL )
|
||||
{
|
||||
g_Material_Blood[1] = g_Mat_BloodPuff[1];
|
||||
}
|
||||
|
||||
Vector vDir;
|
||||
vDir.Random( -1.0f, 1.0f );
|
||||
|
||||
// Gore bits
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Material_Blood[0], origin + RandomVector(-16,16));
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
sParticle->m_flDieTime = random->RandomFloat( 0.25f, 0.5f );
|
||||
|
||||
float speed = random->RandomFloat( 16.0f, 64.0f );
|
||||
|
||||
sParticle->m_vecVelocity.Init();
|
||||
|
||||
sParticle->m_uchColor[0] = 255;
|
||||
sParticle->m_uchColor[1] = 200;
|
||||
sParticle->m_uchColor[2] = 32;
|
||||
sParticle->m_uchStartAlpha = 255;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchStartSize = random->RandomInt( 4, 16 );
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4;
|
||||
sParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = 0.0f;
|
||||
}
|
||||
|
||||
// Middle core
|
||||
SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Material_Blood[1], origin );
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
|
||||
|
||||
float speed = random->RandomFloat( 16.0f, 64.0f );
|
||||
|
||||
sParticle->m_vecVelocity = vDir * -speed;
|
||||
sParticle->m_vecVelocity[2] += 16.0f;
|
||||
|
||||
sParticle->m_uchColor[0] = 255;
|
||||
sParticle->m_uchColor[1] = 200;
|
||||
sParticle->m_uchColor[2] = 32;
|
||||
sParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 3;
|
||||
sParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = random->RandomFloat( -0.2f, 0.2f );
|
||||
|
||||
#else
|
||||
|
||||
//
|
||||
// Non-XBox blood
|
||||
//
|
||||
|
||||
CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "FX_AntlionGib" );
|
||||
pSimple->SetSortOrigin( origin );
|
||||
|
||||
Vector vDir;
|
||||
|
||||
vDir.Random( -1.0f, 1.0f );
|
||||
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[0], origin );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
return;
|
||||
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
|
||||
|
||||
float speed = random->RandomFloat( 16.0f, 64.0f );
|
||||
|
||||
sParticle->m_vecVelocity = vDir * -speed;
|
||||
sParticle->m_vecVelocity[2] += 16.0f;
|
||||
|
||||
sParticle->m_uchColor[0] = 255;
|
||||
sParticle->m_uchColor[1] = 200;
|
||||
sParticle->m_uchColor[2] = 32;
|
||||
sParticle->m_uchStartAlpha = 255;
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
|
||||
sParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
SimpleParticle *sParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), g_Mat_BloodPuff[1], origin );
|
||||
|
||||
if ( sParticle == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sParticle->m_flLifetime = 0.0f;
|
||||
sParticle->m_flDieTime = random->RandomFloat( 0.5f, 0.75f );
|
||||
|
||||
float speed = random->RandomFloat( 16.0f, 64.0f );
|
||||
|
||||
sParticle->m_vecVelocity = vDir * -speed;
|
||||
sParticle->m_vecVelocity[2] += 16.0f;
|
||||
|
||||
sParticle->m_uchColor[0] = 255;
|
||||
sParticle->m_uchColor[1] = 200;
|
||||
sParticle->m_uchColor[2] = 32;
|
||||
sParticle->m_uchStartAlpha = random->RandomInt( 64, 128 );
|
||||
sParticle->m_uchEndAlpha = 0;
|
||||
sParticle->m_uchStartSize = random->RandomInt( 16, 32 );
|
||||
sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2;
|
||||
sParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
sParticle->m_flRollDelta = random->RandomFloat( -1.0f, 1.0f );
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
void AntlionGibCallback( const CEffectData &data )
|
||||
{
|
||||
FX_AntlionGib( data.m_vOrigin, data.m_vNormal, data.m_flScale );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "AntlionGib", AntlionGibCallback );
|
||||
63
game/client/hl2/fx_bugbait.cpp
Normal file
63
game/client/hl2/fx_bugbait.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "particlemgr.h"
|
||||
#include "particle_prototype.h"
|
||||
#include "particle_util.h"
|
||||
#include "particles_simple.h"
|
||||
#include "c_baseentity.h"
|
||||
#include "baseparticleentity.h"
|
||||
#include "engine/ivdebugoverlay.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//==================================================
|
||||
// SporeSmokeEffect
|
||||
//==================================================
|
||||
|
||||
class SporeSmokeEffect : public CSimpleEmitter
|
||||
{
|
||||
public:
|
||||
SporeSmokeEffect( const char *pDebugName ) : CSimpleEmitter( pDebugName ) {}
|
||||
|
||||
static SporeSmokeEffect* Create( const char *pDebugName );
|
||||
|
||||
virtual void UpdateVelocity( SimpleParticle *pParticle, float timeDelta );
|
||||
virtual float UpdateAlpha( const SimpleParticle *pParticle );
|
||||
|
||||
private:
|
||||
SporeSmokeEffect( const SporeSmokeEffect & );
|
||||
};
|
||||
|
||||
|
||||
SporeSmokeEffect* SporeSmokeEffect::Create( const char *pDebugName )
|
||||
{
|
||||
return new SporeSmokeEffect( pDebugName );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pParticle -
|
||||
// timeDelta -
|
||||
// Output : float
|
||||
//-----------------------------------------------------------------------------
|
||||
float SporeSmokeEffect::UpdateAlpha( const SimpleParticle *pParticle )
|
||||
{
|
||||
//return ( ((float)pParticle->m_uchStartAlpha/255.0f) * sin( M_PI * (pParticle->m_flLifetime / pParticle->m_flDieTime) ) );
|
||||
return (pParticle->m_uchStartAlpha/255.0f) + ( (float)(pParticle->m_uchEndAlpha/255.0f) - (float)(pParticle->m_uchStartAlpha/255.0f) ) * (pParticle->m_flLifetime / pParticle->m_flDieTime);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pParticle -
|
||||
// timeDelta -
|
||||
//-----------------------------------------------------------------------------
|
||||
void SporeSmokeEffect::UpdateVelocity( SimpleParticle *pParticle, float timeDelta )
|
||||
{
|
||||
}
|
||||
|
||||
275
game/client/hl2/fx_hl2_impacts.cpp
Normal file
275
game/client/hl2/fx_hl2_impacts.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Game-specific impact effect hooks
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "fx_impact.h"
|
||||
#include "fx.h"
|
||||
#include "decals.h"
|
||||
#include "fx_quad.h"
|
||||
#include "fx_sparks.h"
|
||||
|
||||
#include "tier0/vprof.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle jeep impacts
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImpactJeepCallback( const CEffectData &data )
|
||||
{
|
||||
trace_t tr;
|
||||
Vector vecOrigin, vecStart, vecShotDir;
|
||||
int iMaterial, iDamageType, iHitbox;
|
||||
short nSurfaceProp;
|
||||
C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox );
|
||||
|
||||
if ( !pEntity )
|
||||
{
|
||||
// This happens for impacts that occur on an object that's then destroyed.
|
||||
// Clear out the fraction so it uses the server's data
|
||||
tr.fraction = 1.0;
|
||||
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||||
return;
|
||||
}
|
||||
|
||||
// If we hit, perform our custom effects and play the sound
|
||||
if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr ) )
|
||||
{
|
||||
// Check for custom effects based on the Decal index
|
||||
PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, 2 );
|
||||
}
|
||||
|
||||
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "ImpactJeep", ImpactJeepCallback );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle gauss impacts
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImpactGaussCallback( const CEffectData &data )
|
||||
{
|
||||
trace_t tr;
|
||||
Vector vecOrigin, vecStart, vecShotDir;
|
||||
int iMaterial, iDamageType, iHitbox;
|
||||
short nSurfaceProp;
|
||||
C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox );
|
||||
|
||||
if ( !pEntity )
|
||||
{
|
||||
// This happens for impacts that occur on an object that's then destroyed.
|
||||
// Clear out the fraction so it uses the server's data
|
||||
tr.fraction = 1.0;
|
||||
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||||
return;
|
||||
}
|
||||
|
||||
// If we hit, perform our custom effects and play the sound
|
||||
if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr ) )
|
||||
{
|
||||
// Check for custom effects based on the Decal index
|
||||
PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, 2 );
|
||||
}
|
||||
|
||||
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "ImpactGauss", ImpactGaussCallback );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle weapon impacts
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImpactCallback( const CEffectData &data )
|
||||
{
|
||||
VPROF_BUDGET( "ImpactCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||
|
||||
trace_t tr;
|
||||
Vector vecOrigin, vecStart, vecShotDir;
|
||||
int iMaterial, iDamageType, iHitbox;
|
||||
short nSurfaceProp;
|
||||
C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox );
|
||||
|
||||
if ( !pEntity )
|
||||
{
|
||||
// This happens for impacts that occur on an object that's then destroyed.
|
||||
// Clear out the fraction so it uses the server's data
|
||||
tr.fraction = 1.0;
|
||||
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||||
return;
|
||||
}
|
||||
|
||||
// If we hit, perform our custom effects and play the sound
|
||||
if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr ) )
|
||||
{
|
||||
// Check for custom effects based on the Decal index
|
||||
PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, 1.0 );
|
||||
}
|
||||
|
||||
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "Impact", ImpactCallback );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &origin -
|
||||
// &normal -
|
||||
// scale -
|
||||
//-----------------------------------------------------------------------------
|
||||
void FX_AirboatGunImpact( const Vector &origin, const Vector &normal, float scale )
|
||||
{
|
||||
#ifdef _XBOX
|
||||
|
||||
Vector offset = origin + ( normal * 1.0f );
|
||||
|
||||
CSmartPtr<CTrailParticles> sparkEmitter = CTrailParticles::Create( "FX_MetalSpark 1" );
|
||||
|
||||
if ( sparkEmitter == NULL )
|
||||
return;
|
||||
|
||||
//Setup our information
|
||||
sparkEmitter->SetSortOrigin( offset );
|
||||
sparkEmitter->SetFlag( bitsPARTICLE_TRAIL_VELOCITY_DAMPEN );
|
||||
sparkEmitter->SetVelocityDampen( 8.0f );
|
||||
sparkEmitter->SetGravity( 800.0f );
|
||||
sparkEmitter->SetCollisionDamped( 0.25f );
|
||||
sparkEmitter->GetBinding().SetBBox( offset - Vector( 32, 32, 32 ), offset + Vector( 32, 32, 32 ) );
|
||||
|
||||
int numSparks = random->RandomInt( 4, 8 );
|
||||
|
||||
TrailParticle *pParticle;
|
||||
PMaterialHandle hMaterial = sparkEmitter->GetPMaterial( "effects/spark" );
|
||||
Vector dir;
|
||||
|
||||
float length = 0.1f;
|
||||
|
||||
//Dump out sparks
|
||||
for ( int i = 0; i < numSparks; i++ )
|
||||
{
|
||||
pParticle = (TrailParticle *) sparkEmitter->AddParticle( sizeof(TrailParticle), hMaterial, offset );
|
||||
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
|
||||
|
||||
float spreadOfs = random->RandomFloat( 0.0f, 2.0f );
|
||||
|
||||
dir[0] = normal[0] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) );
|
||||
dir[1] = normal[1] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) );
|
||||
dir[2] = normal[2] + random->RandomFloat( -(0.5f*spreadOfs), (0.5f*spreadOfs) );
|
||||
|
||||
VectorNormalize( dir );
|
||||
|
||||
pParticle->m_flWidth = random->RandomFloat( 1.0f, 4.0f );
|
||||
pParticle->m_flLength = random->RandomFloat( length*0.25f, length );
|
||||
|
||||
pParticle->m_vecVelocity = dir * random->RandomFloat( (128.0f*(2.0f-spreadOfs)), (512.0f*(2.0f-spreadOfs)) );
|
||||
|
||||
Color32Init( pParticle->m_color, 255, 255, 255, 255 );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Normal metal spark
|
||||
FX_MetalSpark( origin, normal, normal, (int) scale );
|
||||
|
||||
#endif // _XBOX
|
||||
|
||||
// Add a quad to highlite the hit point
|
||||
FX_AddQuad( origin,
|
||||
normal,
|
||||
random->RandomFloat( 16, 32 ),
|
||||
random->RandomFloat( 32, 48 ),
|
||||
0.75f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
0.4f,
|
||||
random->RandomInt( 0, 360 ),
|
||||
0,
|
||||
Vector( 1.0f, 1.0f, 1.0f ),
|
||||
0.05f,
|
||||
"effects/combinemuzzle2_nocull",
|
||||
(FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle weapon impacts from the airboat gun shooting (cheaper versions)
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImpactAirboatGunCallback( const CEffectData &data )
|
||||
{
|
||||
VPROF_BUDGET( "ImpactAirboatGunCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||
|
||||
trace_t tr;
|
||||
Vector vecOrigin, vecStart, vecShotDir;
|
||||
int iMaterial, iDamageType, iHitbox;
|
||||
short nSurfaceProp;
|
||||
C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox );
|
||||
|
||||
if ( !pEntity )
|
||||
{
|
||||
// This happens for impacts that occur on an object that's then destroyed.
|
||||
// Clear out the fraction so it uses the server's data
|
||||
tr.fraction = 1.0;
|
||||
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined( _XBOX )
|
||||
// If we hit, perform our custom effects and play the sound. Don't create decals
|
||||
if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr, IMPACT_NODECAL | IMPACT_REPORT_RAGDOLL_IMPACTS ) )
|
||||
{
|
||||
FX_AirboatGunImpact( vecOrigin, tr.plane.normal, 2 );
|
||||
}
|
||||
#else
|
||||
FX_AirboatGunImpact( vecOrigin, tr.plane.normal, 1 );
|
||||
#endif
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "AirboatGunImpact", ImpactAirboatGunCallback );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Handle weapon impacts from the helicopter shooting (cheaper versions)
|
||||
//-----------------------------------------------------------------------------
|
||||
void ImpactHelicopterCallback( const CEffectData &data )
|
||||
{
|
||||
VPROF_BUDGET( "ImpactHelicopterCallback", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||
|
||||
trace_t tr;
|
||||
Vector vecOrigin, vecStart, vecShotDir;
|
||||
int iMaterial, iDamageType, iHitbox;
|
||||
short nSurfaceProp;
|
||||
C_BaseEntity *pEntity = ParseImpactData( data, &vecOrigin, &vecStart, &vecShotDir, nSurfaceProp, iMaterial, iDamageType, iHitbox );
|
||||
|
||||
if ( !pEntity )
|
||||
{
|
||||
// This happens for impacts that occur on an object that's then destroyed.
|
||||
// Clear out the fraction so it uses the server's data
|
||||
tr.fraction = 1.0;
|
||||
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||||
return;
|
||||
}
|
||||
|
||||
// If we hit, perform our custom effects and play the sound. Don't create decals
|
||||
if ( Impact( vecOrigin, vecStart, iMaterial, iDamageType, iHitbox, pEntity, tr, IMPACT_NODECAL | IMPACT_REPORT_RAGDOLL_IMPACTS ) )
|
||||
{
|
||||
FX_AirboatGunImpact( vecOrigin, tr.plane.normal, IsXbox() ? 1 : 2 );
|
||||
|
||||
// Only do metal + computer custom effects
|
||||
if ( (iMaterial == CHAR_TEX_METAL) || (iMaterial == CHAR_TEX_COMPUTER) )
|
||||
{
|
||||
PerformCustomEffects( vecOrigin, tr, vecShotDir, iMaterial, 1.0, FLAGS_CUSTIOM_EFFECTS_NOFLECKS );
|
||||
}
|
||||
}
|
||||
|
||||
PlayImpactSound( pEntity, tr, vecOrigin, nSurfaceProp );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "HelicopterImpact", ImpactHelicopterCallback );
|
||||
|
||||
695
game/client/hl2/fx_hl2_tracers.cpp
Normal file
695
game/client/hl2/fx_hl2_tracers.cpp
Normal file
@@ -0,0 +1,695 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Game-specific impact effect hooks
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "fx.h"
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#include "tier0/vprof.h"
|
||||
#include "fx_line.h"
|
||||
#include "fx_quad.h"
|
||||
#include "view.h"
|
||||
#include "particles_localspace.h"
|
||||
#include "dlight.h"
|
||||
#include "iefx.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
extern Vector GetTracerOrigin( const CEffectData &data );
|
||||
extern void FX_TracerSound( const Vector &start, const Vector &end, int iTracerType );
|
||||
|
||||
extern ConVar muzzleflash_light;
|
||||
|
||||
|
||||
CLIENTEFFECT_REGISTER_BEGIN( PrecacheTracers )
|
||||
CLIENTEFFECT_MATERIAL( "effects/gunshiptracer" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle1" )
|
||||
CLIENTEFFECT_MATERIAL( "effects/combinemuzzle2_nocull" )
|
||||
CLIENTEFFECT_REGISTER_END()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gunship's Tracer
|
||||
//-----------------------------------------------------------------------------
|
||||
void GunshipTracerCallback( const CEffectData &data )
|
||||
{
|
||||
float flVelocity = data.m_flScale;
|
||||
bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
|
||||
FX_GunshipTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "GunshipTracer", GunshipTracerCallback );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Strider's Tracer
|
||||
//-----------------------------------------------------------------------------
|
||||
void StriderTracerCallback( const CEffectData &data )
|
||||
{
|
||||
float flVelocity = data.m_flScale;
|
||||
bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
|
||||
FX_StriderTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "StriderTracer", StriderTracerCallback );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Hunter's Tracer
|
||||
//-----------------------------------------------------------------------------
|
||||
void HunterTracerCallback( const CEffectData &data )
|
||||
{
|
||||
float flVelocity = data.m_flScale;
|
||||
bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
|
||||
FX_HunterTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "HunterTracer", HunterTracerCallback );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Gauss Gun's Tracer
|
||||
//-----------------------------------------------------------------------------
|
||||
void GaussTracerCallback( const CEffectData &data )
|
||||
{
|
||||
float flVelocity = data.m_flScale;
|
||||
bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
|
||||
FX_GaussTracer( (Vector&)data.m_vStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "GaussTracer", GaussTracerCallback );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Airboat gun tracers
|
||||
//-----------------------------------------------------------------------------
|
||||
void AirboatGunHeavyTracerCallback( const CEffectData &data )
|
||||
{
|
||||
// Grab the data
|
||||
Vector vecStart = GetTracerOrigin( data );
|
||||
float flVelocity = data.m_flScale;
|
||||
|
||||
// Use default velocity if none specified
|
||||
if ( !flVelocity )
|
||||
{
|
||||
flVelocity = 8000;
|
||||
}
|
||||
|
||||
//Get out shot direction and length
|
||||
Vector vecShotDir;
|
||||
VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
|
||||
float flTotalDist = VectorNormalize( vecShotDir );
|
||||
|
||||
// Don't make small tracers
|
||||
if ( flTotalDist <= 64 )
|
||||
return;
|
||||
|
||||
float flLength = random->RandomFloat( 300.0f, 400.0f );
|
||||
float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
|
||||
|
||||
// Add it
|
||||
FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 5.0f, flLife, "effects/gunshiptracer" );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "AirboatGunHeavyTracer", AirboatGunHeavyTracerCallback );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Airboat gun tracers
|
||||
//-----------------------------------------------------------------------------
|
||||
void AirboatGunTracerCallback( const CEffectData &data )
|
||||
{
|
||||
// Grab the data
|
||||
Vector vecStart = GetTracerOrigin( data );
|
||||
float flVelocity = data.m_flScale;
|
||||
|
||||
// Use default velocity if none specified
|
||||
if ( !flVelocity )
|
||||
{
|
||||
flVelocity = 10000;
|
||||
}
|
||||
|
||||
//Get out shot direction and length
|
||||
Vector vecShotDir;
|
||||
VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
|
||||
float flTotalDist = VectorNormalize( vecShotDir );
|
||||
|
||||
// Don't make small tracers
|
||||
if ( flTotalDist <= 64 )
|
||||
return;
|
||||
|
||||
float flLength = random->RandomFloat( 256.0f, 384.0f );
|
||||
float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
|
||||
|
||||
// Add it
|
||||
FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 2.0f, flLife, "effects/gunshiptracer" );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "AirboatGunTracer", AirboatGunTracerCallback );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Airboat gun tracers
|
||||
//-----------------------------------------------------------------------------
|
||||
void HelicopterTracerCallback( const CEffectData &data )
|
||||
{
|
||||
// Grab the data
|
||||
Vector vecStart = GetTracerOrigin( data );
|
||||
float flVelocity = data.m_flScale;
|
||||
|
||||
// Use default velocity if none specified
|
||||
if ( !flVelocity )
|
||||
{
|
||||
flVelocity = 8000;
|
||||
}
|
||||
|
||||
//Get out shot direction and length
|
||||
Vector vecShotDir;
|
||||
VectorSubtract( data.m_vOrigin, vecStart, vecShotDir );
|
||||
float flTotalDist = VectorNormalize( vecShotDir );
|
||||
|
||||
// Don't make small tracers
|
||||
if ( flTotalDist <= 256 )
|
||||
return;
|
||||
|
||||
float flLength = random->RandomFloat( 256.0f, 384.0f );
|
||||
float flLife = ( flTotalDist + flLength ) / flVelocity; //NOTENOTE: We want the tail to finish its run as well
|
||||
|
||||
// Add it
|
||||
FX_AddDiscreetLine( vecStart, vecShotDir, flVelocity, flLength, flTotalDist, 5.0f, flLife, "effects/gunshiptracer" );
|
||||
|
||||
if (data.m_fFlags & TRACER_FLAG_WHIZ)
|
||||
{
|
||||
FX_TracerSound( vecStart, data.m_vOrigin, TRACER_TYPE_GUNSHIP );
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "HelicopterTracer", HelicopterTracerCallback );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : start -
|
||||
// end -
|
||||
//-----------------------------------------------------------------------------
|
||||
void FX_PlayerAR2Tracer( const Vector &start, const Vector &end )
|
||||
{
|
||||
VPROF_BUDGET( "FX_PlayerAR2Tracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||
|
||||
Vector shotDir, dStart, dEnd;
|
||||
float length;
|
||||
|
||||
//Find the direction of the tracer
|
||||
VectorSubtract( end, start, shotDir );
|
||||
length = VectorNormalize( shotDir );
|
||||
|
||||
//We don't want to draw them if they're too close to us
|
||||
if ( length < 128 )
|
||||
return;
|
||||
|
||||
//Randomly place the tracer along this line, with a random length
|
||||
VectorMA( start, random->RandomFloat( 0.0f, 8.0f ), shotDir, dStart );
|
||||
VectorMA( dStart, MIN( length, random->RandomFloat( 256.0f, 1024.0f ) ), shotDir, dEnd );
|
||||
|
||||
//Create the line
|
||||
CFXStaticLine *tracerLine = new CFXStaticLine( "Tracer", dStart, dEnd, random->RandomFloat( 6.0f, 12.0f ), 0.01f, "effects/gunshiptracer", 0 );
|
||||
assert( tracerLine );
|
||||
|
||||
//Throw it into the list
|
||||
clienteffects->AddEffect( tracerLine );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : start -
|
||||
// end -
|
||||
// velocity -
|
||||
// makeWhiz -
|
||||
//-----------------------------------------------------------------------------
|
||||
void FX_AR2Tracer( Vector& start, Vector& end, int velocity, bool makeWhiz )
|
||||
{
|
||||
VPROF_BUDGET( "FX_AR2Tracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||
|
||||
//Don't make small tracers
|
||||
float dist;
|
||||
Vector dir;
|
||||
|
||||
VectorSubtract( end, start, dir );
|
||||
dist = VectorNormalize( dir );
|
||||
|
||||
// Don't make short tracers.
|
||||
if ( dist < 128 )
|
||||
return;
|
||||
|
||||
float length = random->RandomFloat( 128.0f, 256.0f );
|
||||
float life = ( dist + length ) / velocity; //NOTENOTE: We want the tail to finish its run as well
|
||||
|
||||
//Add it
|
||||
FX_AddDiscreetLine( start, dir, velocity, length, dist, random->RandomFloat( 0.5f, 1.5f ), life, "effects/gunshiptracer" );
|
||||
|
||||
if( makeWhiz )
|
||||
{
|
||||
FX_TracerSound( start, end, TRACER_TYPE_GUNSHIP );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void AR2TracerCallback( const CEffectData &data )
|
||||
{
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
|
||||
if ( player == NULL )
|
||||
return;
|
||||
|
||||
// Grab the data
|
||||
Vector vecStart = GetTracerOrigin( data );
|
||||
float flVelocity = data.m_flScale;
|
||||
bool bWhiz = (data.m_fFlags & TRACER_FLAG_WHIZ);
|
||||
int iEntIndex = data.entindex();
|
||||
|
||||
if ( iEntIndex && iEntIndex == player->index )
|
||||
{
|
||||
Vector foo = data.m_vStart;
|
||||
QAngle vangles;
|
||||
Vector vforward, vright, vup;
|
||||
|
||||
engine->GetViewAngles( vangles );
|
||||
AngleVectors( vangles, &vforward, &vright, &vup );
|
||||
|
||||
VectorMA( data.m_vStart, 4, vright, foo );
|
||||
foo[2] -= 0.5f;
|
||||
|
||||
FX_PlayerAR2Tracer( foo, (Vector&)data.m_vOrigin );
|
||||
return;
|
||||
}
|
||||
|
||||
// Use default velocity if none specified
|
||||
if ( !flVelocity )
|
||||
{
|
||||
flVelocity = 8000;
|
||||
}
|
||||
|
||||
// Do tracer effect
|
||||
FX_AR2Tracer( (Vector&)vecStart, (Vector&)data.m_vOrigin, flVelocity, bWhiz );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "AR2Tracer", AR2TracerCallback );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
void AR2ExplosionCallback( const CEffectData &data )
|
||||
{
|
||||
float lifetime = random->RandomFloat( 0.4f, 0.75f );
|
||||
|
||||
// Ground splash
|
||||
FX_AddQuad( data.m_vOrigin,
|
||||
data.m_vNormal,
|
||||
data.m_flRadius,
|
||||
data.m_flRadius * 4.0f,
|
||||
0.85f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
0.25f,
|
||||
random->RandomInt( 0, 360 ),
|
||||
random->RandomFloat( -4, 4 ),
|
||||
Vector( 1.0f, 1.0f, 1.0f ),
|
||||
lifetime,
|
||||
"effects/combinemuzzle1",
|
||||
(FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
|
||||
|
||||
Vector vRight, vUp;
|
||||
VectorVectors( data.m_vNormal, vRight, vUp );
|
||||
|
||||
Vector start, end;
|
||||
|
||||
float radius = data.m_flRadius * 0.15f;
|
||||
|
||||
// Base vertical shaft
|
||||
FXLineData_t lineData;
|
||||
|
||||
start = data.m_vOrigin;
|
||||
end = start + ( data.m_vNormal * random->RandomFloat( radius*2.0f, radius*4.0f ) );
|
||||
|
||||
lineData.m_flDieTime = lifetime;
|
||||
|
||||
lineData.m_flStartAlpha= 1.0f;
|
||||
lineData.m_flEndAlpha = 0.0f;
|
||||
|
||||
lineData.m_flStartScale = radius*4;
|
||||
lineData.m_flEndScale = radius*5;
|
||||
|
||||
lineData.m_pMaterial = materials->FindMaterial( "effects/ar2ground2", 0, 0 );
|
||||
|
||||
lineData.m_vecStart = start;
|
||||
lineData.m_vecStartVelocity = vec3_origin;
|
||||
|
||||
lineData.m_vecEnd = end;
|
||||
lineData.m_vecEndVelocity = data.m_vNormal * random->RandomFloat( 200, 350 );
|
||||
|
||||
FX_AddLine( lineData );
|
||||
|
||||
// Inner filler shaft
|
||||
start = data.m_vOrigin;
|
||||
end = start + ( data.m_vNormal * random->RandomFloat( 16, radius*0.25f ) );
|
||||
|
||||
lineData.m_flDieTime = lifetime - 0.1f;
|
||||
|
||||
lineData.m_flStartAlpha= 1.0f;
|
||||
lineData.m_flEndAlpha = 0.0f;
|
||||
|
||||
lineData.m_flStartScale = radius*2;
|
||||
lineData.m_flEndScale = radius*4;
|
||||
|
||||
lineData.m_pMaterial = materials->FindMaterial( "effects/ar2ground2", 0, 0 );
|
||||
|
||||
lineData.m_vecStart = start;
|
||||
lineData.m_vecStartVelocity = vec3_origin;
|
||||
|
||||
lineData.m_vecEnd = end;
|
||||
lineData.m_vecEndVelocity = data.m_vNormal * random->RandomFloat( 64, 128 );
|
||||
|
||||
FX_AddLine( lineData );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "AR2Explosion", AR2ExplosionCallback );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : &data -
|
||||
//-----------------------------------------------------------------------------
|
||||
void AR2ImpactCallback( const CEffectData &data )
|
||||
{
|
||||
FX_AddQuad( data.m_vOrigin,
|
||||
data.m_vNormal,
|
||||
random->RandomFloat( 24, 32 ),
|
||||
0,
|
||||
0.75f,
|
||||
1.0f,
|
||||
0.0f,
|
||||
0.4f,
|
||||
random->RandomInt( 0, 360 ),
|
||||
0,
|
||||
Vector( 1.0f, 1.0f, 1.0f ),
|
||||
0.25f,
|
||||
"effects/combinemuzzle2_nocull",
|
||||
(FXQUAD_BIAS_SCALE|FXQUAD_BIAS_ALPHA) );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "AR2Impact", AR2ImpactCallback );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates a muzzleflash elight
|
||||
//-----------------------------------------------------------------------------
|
||||
void CreateMuzzleflashELight( const Vector &origin, int exponent, int nMinRadius, int nMaxRadius, ClientEntityHandle_t hEntity )
|
||||
{
|
||||
if ( muzzleflash_light.GetInt() )
|
||||
{
|
||||
int entityIndex = ClientEntityList().HandleToEntIndex( hEntity );
|
||||
if ( entityIndex >= 0 )
|
||||
{
|
||||
dlight_t *el = effects->CL_AllocElight( LIGHT_INDEX_MUZZLEFLASH + entityIndex );
|
||||
|
||||
el->origin = origin;
|
||||
|
||||
el->color.r = 255;
|
||||
el->color.g = 192;
|
||||
el->color.b = 64;
|
||||
el->color.exponent = exponent;
|
||||
|
||||
el->radius = random->RandomInt( nMinRadius, nMaxRadius );
|
||||
el->decay = el->radius / 0.05f;
|
||||
el->die = gpGlobals->curtime + 0.1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Airboat muzzle flashes
|
||||
//-----------------------------------------------------------------------------
|
||||
void MuzzleFlash_Airboat( ClientEntityHandle_t hEntity, int attachmentIndex )
|
||||
{
|
||||
VPROF_BUDGET( "MuzzleFlash_Airboat", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||
|
||||
CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
|
||||
|
||||
SimpleParticle *pParticle;
|
||||
Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
|
||||
|
||||
float flScale = random->RandomFloat( 0.75f, IsXbox() ? 2.0f : 2.5f );
|
||||
|
||||
PMaterialHandle pMuzzle[2];
|
||||
pMuzzle[0] = pSimple->GetPMaterial( "effects/combinemuzzle1" );
|
||||
pMuzzle[1] = pSimple->GetPMaterial( "effects/combinemuzzle2" );
|
||||
|
||||
// Flash
|
||||
for ( int i = 1; i < 7; i++ )
|
||||
{
|
||||
offset = (forward * (i*6.0f*flScale));
|
||||
|
||||
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pMuzzle[random->RandomInt(0,1)], offset );
|
||||
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = IsXbox() ? 0.0001f : 0.01f;
|
||||
|
||||
pParticle->m_vecVelocity.Init();
|
||||
|
||||
pParticle->m_uchColor[0] = 255;
|
||||
pParticle->m_uchColor[1] = 255;
|
||||
pParticle->m_uchColor[2] = 255;
|
||||
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 128;
|
||||
|
||||
pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (9-(i))/7) * flScale );
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize;
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta = 0.0f;
|
||||
}
|
||||
|
||||
// Tack on the smoke
|
||||
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "sprites/ar2_muzzle1" ), vec3_origin );
|
||||
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = 0.05f;
|
||||
|
||||
pParticle->m_vecVelocity.Init();
|
||||
|
||||
pParticle->m_uchColor[0] = 255;
|
||||
pParticle->m_uchColor[1] = 255;
|
||||
pParticle->m_uchColor[2] = 255;
|
||||
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 128;
|
||||
|
||||
pParticle->m_uchStartSize = random->RandomFloat( 16.0f, 24.0f );
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize;
|
||||
|
||||
float spokePos = random->RandomInt( 0, 5 );
|
||||
|
||||
pParticle->m_flRoll = (360.0/6.0f)*spokePos;
|
||||
pParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
#ifndef _XBOX
|
||||
// Grab the origin out of the transform for the attachment
|
||||
if ( muzzleflash_light.GetInt() )
|
||||
{
|
||||
// If the client hasn't seen this entity yet, bail.
|
||||
matrix3x4_t matAttachment;
|
||||
if ( FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
|
||||
{
|
||||
Vector origin;
|
||||
MatrixGetColumn( matAttachment, 3, &origin );
|
||||
CreateMuzzleflashELight( origin, 5, 64, 128, hEntity );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void AirboatMuzzleFlashCallback( const CEffectData &data )
|
||||
{
|
||||
MuzzleFlash_Airboat( data.m_hEntity, data.m_nAttachmentIndex );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "AirboatMuzzleFlash", AirboatMuzzleFlashCallback );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Chopper muzzle flashes
|
||||
//-----------------------------------------------------------------------------
|
||||
void MuzzleFlash_Chopper( ClientEntityHandle_t hEntity, int attachmentIndex )
|
||||
{
|
||||
VPROF_BUDGET( "MuzzleFlash_Chopper", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||
|
||||
matrix3x4_t matAttachment;
|
||||
// If the client hasn't seen this entity yet, bail.
|
||||
if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
|
||||
return;
|
||||
|
||||
CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
|
||||
|
||||
SimpleParticle *pParticle;
|
||||
Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
|
||||
|
||||
float flScale = random->RandomFloat( 2.5f, 4.5f );
|
||||
|
||||
// Flash
|
||||
for ( int i = 1; i < 7; i++ )
|
||||
{
|
||||
offset = (forward * (i*2.0f*flScale));
|
||||
|
||||
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( VarArgs( "effects/combinemuzzle%d", random->RandomInt(1,2) ) ), offset );
|
||||
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
|
||||
|
||||
pParticle->m_vecVelocity.Init();
|
||||
|
||||
pParticle->m_uchColor[0] = 255;
|
||||
pParticle->m_uchColor[1] = 255;
|
||||
pParticle->m_uchColor[2] = 255;
|
||||
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 128;
|
||||
|
||||
pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * (10-(i))/7) * flScale );
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize;
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta = 0.0f;
|
||||
}
|
||||
|
||||
// Grab the origin out of the transform for the attachment
|
||||
Vector origin;
|
||||
MatrixGetColumn( matAttachment, 3, &origin );
|
||||
CreateMuzzleflashELight( origin, 6, 128, 256, hEntity );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void ChopperMuzzleFlashCallback( const CEffectData &data )
|
||||
{
|
||||
MuzzleFlash_Chopper( data.m_hEntity, data.m_nAttachmentIndex );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "ChopperMuzzleFlash", ChopperMuzzleFlashCallback );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gunship muzzle flashes
|
||||
//-----------------------------------------------------------------------------
|
||||
void MuzzleFlash_Gunship( ClientEntityHandle_t hEntity, int attachmentIndex )
|
||||
{
|
||||
VPROF_BUDGET( "MuzzleFlash_Gunship", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||
|
||||
// If the client hasn't seen this entity yet, bail.
|
||||
matrix3x4_t matAttachment;
|
||||
if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
|
||||
return;
|
||||
|
||||
CSmartPtr<CLocalSpaceEmitter> pSimple = CLocalSpaceEmitter::Create( "MuzzleFlash", hEntity, attachmentIndex );
|
||||
|
||||
SimpleParticle *pParticle;
|
||||
Vector forward(1,0,0), offset; //NOTENOTE: All coords are in local space
|
||||
|
||||
float flScale = random->RandomFloat( 2.5f, 4.5f );
|
||||
|
||||
// Flash
|
||||
offset = (forward * (2.0f*flScale));
|
||||
|
||||
pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/gunshipmuzzle" ), offset );
|
||||
if ( pParticle == NULL )
|
||||
return;
|
||||
|
||||
pParticle->m_flLifetime = 0.0f;
|
||||
pParticle->m_flDieTime = random->RandomFloat( 0.05f, 0.1f );
|
||||
|
||||
pParticle->m_vecVelocity.Init();
|
||||
|
||||
pParticle->m_uchColor[0] = 255;
|
||||
pParticle->m_uchColor[1] = 255;
|
||||
pParticle->m_uchColor[2] = 255;
|
||||
|
||||
pParticle->m_uchStartAlpha = 255;
|
||||
pParticle->m_uchEndAlpha = 128;
|
||||
|
||||
pParticle->m_uchStartSize = ( (random->RandomFloat( 6.0f, 8.0f ) * 10.0/7.0) * flScale );
|
||||
pParticle->m_uchEndSize = pParticle->m_uchStartSize;
|
||||
pParticle->m_flRoll = random->RandomInt( 0, 360 );
|
||||
pParticle->m_flRollDelta = 0.0f;
|
||||
|
||||
// Grab the origin out of the transform for the attachment
|
||||
Vector origin;
|
||||
MatrixGetColumn( matAttachment, 3, &origin );
|
||||
CreateMuzzleflashELight( origin, 6, 128, 256, hEntity );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void GunshipMuzzleFlashCallback( const CEffectData &data )
|
||||
{
|
||||
MuzzleFlash_Gunship( data.m_hEntity, data.m_nAttachmentIndex );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "GunshipMuzzleFlash", GunshipMuzzleFlashCallback );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hunter muzzle flashes
|
||||
//-----------------------------------------------------------------------------
|
||||
void MuzzleFlash_Hunter( ClientEntityHandle_t hEntity, int attachmentIndex )
|
||||
{
|
||||
VPROF_BUDGET( "MuzzleFlash_Hunter", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
|
||||
|
||||
// If the client hasn't seen this entity yet, bail.
|
||||
matrix3x4_t matAttachment;
|
||||
if ( !FX_GetAttachmentTransform( hEntity, attachmentIndex, matAttachment ) )
|
||||
return;
|
||||
|
||||
// Grab the origin out of the transform for the attachment
|
||||
Vector origin;
|
||||
MatrixGetColumn( matAttachment, 3, &origin );
|
||||
|
||||
dlight_t *el = effects->CL_AllocElight( LIGHT_INDEX_MUZZLEFLASH );
|
||||
el->origin = origin;// + Vector( 12.0f, 0, 0 );
|
||||
|
||||
el->color.r = 50;
|
||||
el->color.g = 222;
|
||||
el->color.b = 213;
|
||||
el->color.exponent = 5;
|
||||
|
||||
el->radius = random->RandomInt( 120, 200 );
|
||||
el->decay = el->radius / 0.05f;
|
||||
el->die = gpGlobals->curtime + 0.05f;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void HunterMuzzleFlashCallback( const CEffectData &data )
|
||||
{
|
||||
MuzzleFlash_Hunter( data.m_hEntity, data.m_nAttachmentIndex );
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "HunterMuzzleFlash", HunterMuzzleFlashCallback );
|
||||
77
game/client/hl2/hl2_clientmode.cpp
Normal file
77
game/client/hl2/hl2_clientmode.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "ivmodemanager.h"
|
||||
#include "clientmode_hlnormal.h"
|
||||
#include "panelmetaclassmgr.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// default FOV for HL2
|
||||
ConVar default_fov( "default_fov", "75", FCVAR_CHEAT );
|
||||
|
||||
// The current client mode. Always ClientModeNormal in HL.
|
||||
IClientMode *g_pClientMode = NULL;
|
||||
|
||||
#define SCREEN_FILE "scripts/vgui_screens.txt"
|
||||
|
||||
class CHLModeManager : public IVModeManager
|
||||
{
|
||||
public:
|
||||
CHLModeManager( void );
|
||||
virtual ~CHLModeManager( void );
|
||||
|
||||
virtual void Init( void );
|
||||
virtual void SwitchMode( bool commander, bool force );
|
||||
virtual void OverrideView( CViewSetup *pSetup );
|
||||
virtual void CreateMove( float flInputSampleTime, CUserCmd *cmd );
|
||||
virtual void LevelInit( const char *newmap );
|
||||
virtual void LevelShutdown( void );
|
||||
};
|
||||
|
||||
CHLModeManager::CHLModeManager( void )
|
||||
{
|
||||
}
|
||||
|
||||
CHLModeManager::~CHLModeManager( void )
|
||||
{
|
||||
}
|
||||
|
||||
void CHLModeManager::Init( void )
|
||||
{
|
||||
g_pClientMode = GetClientModeNormal();
|
||||
PanelMetaClassMgr()->LoadMetaClassDefinitionFile( SCREEN_FILE );
|
||||
}
|
||||
|
||||
void CHLModeManager::SwitchMode( bool commander, bool force )
|
||||
{
|
||||
}
|
||||
|
||||
void CHLModeManager::OverrideView( CViewSetup *pSetup )
|
||||
{
|
||||
}
|
||||
|
||||
void CHLModeManager::CreateMove( float flInputSampleTime, CUserCmd *cmd )
|
||||
{
|
||||
}
|
||||
|
||||
void CHLModeManager::LevelInit( const char *newmap )
|
||||
{
|
||||
g_pClientMode->LevelInit( newmap );
|
||||
}
|
||||
|
||||
void CHLModeManager::LevelShutdown( void )
|
||||
{
|
||||
g_pClientMode->LevelShutdown();
|
||||
}
|
||||
|
||||
|
||||
static CHLModeManager g_HLModeManager;
|
||||
IVModeManager *modemanager = &g_HLModeManager;
|
||||
|
||||
25
game/client/hl2/hl_in_main.cpp
Normal file
25
game/client/hl2/hl_in_main.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: HL2 specific input handling
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "kbutton.h"
|
||||
#include "input.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: HL Input interface
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHLInput : public CInput
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
static CHLInput g_Input;
|
||||
|
||||
// Expose this interface
|
||||
IInput *input = ( IInput * )&g_Input;
|
||||
24
game/client/hl2/hl_prediction.cpp
Normal file
24
game/client/hl2/hl_prediction.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "prediction.h"
|
||||
#include "hl_movedata.h"
|
||||
#include "c_basehlplayer.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
static CHLMoveData g_HLMoveData;
|
||||
CMoveData *g_pMoveData = &g_HLMoveData;
|
||||
|
||||
// Expose interface to engine
|
||||
static CPrediction g_Prediction;
|
||||
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CPrediction, IPrediction, VCLIENT_PREDICTION_INTERFACE_VERSION, g_Prediction );
|
||||
|
||||
CPrediction *prediction = &g_Prediction;
|
||||
|
||||
502
game/client/hl2/hud_ammo.cpp
Normal file
502
game/client/hl2/hud_ammo.cpp
Normal file
@@ -0,0 +1,502 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hudelement.h"
|
||||
#include "hud_macros.h"
|
||||
#include "hud_numericdisplay.h"
|
||||
#include "iclientmode.h"
|
||||
#include "iclientvehicle.h"
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include "ihudlcd.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Displays current ammunition level
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudAmmo : public CHudNumericDisplay, public CHudElement
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudAmmo, CHudNumericDisplay );
|
||||
|
||||
public:
|
||||
CHudAmmo( const char *pElementName );
|
||||
void Init( void );
|
||||
void VidInit( void );
|
||||
void Reset();
|
||||
|
||||
void SetAmmo(int ammo, bool playAnimation);
|
||||
void SetAmmo2(int ammo2, bool playAnimation);
|
||||
virtual void Paint( void );
|
||||
|
||||
protected:
|
||||
virtual void OnThink();
|
||||
|
||||
void UpdateAmmoDisplays();
|
||||
void UpdatePlayerAmmo( C_BasePlayer *player );
|
||||
void UpdateVehicleAmmo( C_BasePlayer *player, IClientVehicle *pVehicle );
|
||||
|
||||
private:
|
||||
CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
|
||||
CHandle< C_BaseEntity > m_hCurrentVehicle;
|
||||
int m_iAmmo;
|
||||
int m_iAmmo2;
|
||||
CHudTexture *m_iconPrimaryAmmo;
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHudAmmo );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudAmmo::CHudAmmo( const char *pElementName ) : BaseClass(NULL, "HudAmmo"), CHudElement( pElementName )
|
||||
{
|
||||
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT | HIDEHUD_WEAPONSELECTION );
|
||||
|
||||
hudlcd->SetGlobalStat( "(ammo_primary)", "0" );
|
||||
hudlcd->SetGlobalStat( "(ammo_secondary)", "0" );
|
||||
hudlcd->SetGlobalStat( "(weapon_print_name)", "" );
|
||||
hudlcd->SetGlobalStat( "(weapon_name)", "" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudAmmo::Init( void )
|
||||
{
|
||||
m_iAmmo = -1;
|
||||
m_iAmmo2 = -1;
|
||||
|
||||
m_iconPrimaryAmmo = NULL;
|
||||
|
||||
wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AMMO");
|
||||
if (tempString)
|
||||
{
|
||||
SetLabelText(tempString);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLabelText(L"AMMO");
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudAmmo::VidInit( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Resets hud after save/restore
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudAmmo::Reset()
|
||||
{
|
||||
BaseClass::Reset();
|
||||
|
||||
m_hCurrentActiveWeapon = NULL;
|
||||
m_hCurrentVehicle = NULL;
|
||||
m_iAmmo = 0;
|
||||
m_iAmmo2 = 0;
|
||||
|
||||
UpdateAmmoDisplays();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called every frame to get ammo info from the weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudAmmo::UpdatePlayerAmmo( C_BasePlayer *player )
|
||||
{
|
||||
// Clear out the vehicle entity
|
||||
m_hCurrentVehicle = NULL;
|
||||
|
||||
C_BaseCombatWeapon *wpn = GetActiveWeapon();
|
||||
|
||||
hudlcd->SetGlobalStat( "(weapon_print_name)", wpn ? wpn->GetPrintName() : " " );
|
||||
hudlcd->SetGlobalStat( "(weapon_name)", wpn ? wpn->GetName() : " " );
|
||||
|
||||
if ( !wpn || !player || !wpn->UsesPrimaryAmmo() )
|
||||
{
|
||||
hudlcd->SetGlobalStat( "(ammo_primary)", "n/a" );
|
||||
hudlcd->SetGlobalStat( "(ammo_secondary)", "n/a" );
|
||||
|
||||
SetPaintEnabled(false);
|
||||
SetPaintBackgroundEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SetPaintEnabled(true);
|
||||
SetPaintBackgroundEnabled(true);
|
||||
|
||||
// Get our icons for the ammo types
|
||||
m_iconPrimaryAmmo = gWR.GetAmmoIconFromWeapon( wpn->GetPrimaryAmmoType() );
|
||||
|
||||
// get the ammo in our clip
|
||||
int ammo1 = wpn->Clip1();
|
||||
int ammo2;
|
||||
if (ammo1 < 0)
|
||||
{
|
||||
// we don't use clip ammo, just use the total ammo count
|
||||
ammo1 = player->GetAmmoCount(wpn->GetPrimaryAmmoType());
|
||||
ammo2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we use clip ammo, so the second ammo is the total ammo
|
||||
ammo2 = player->GetAmmoCount(wpn->GetPrimaryAmmoType());
|
||||
}
|
||||
|
||||
hudlcd->SetGlobalStat( "(ammo_primary)", VarArgs( "%d", ammo1 ) );
|
||||
hudlcd->SetGlobalStat( "(ammo_secondary)", VarArgs( "%d", ammo2 ) );
|
||||
|
||||
if (wpn == m_hCurrentActiveWeapon)
|
||||
{
|
||||
// same weapon, just update counts
|
||||
SetAmmo(ammo1, true);
|
||||
SetAmmo2(ammo2, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// diferent weapon, change without triggering
|
||||
SetAmmo(ammo1, false);
|
||||
SetAmmo2(ammo2, false);
|
||||
|
||||
// update whether or not we show the total ammo display
|
||||
if (wpn->UsesClipsForAmmo1())
|
||||
{
|
||||
SetShouldDisplaySecondaryValue(true);
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesClips");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseClips");
|
||||
SetShouldDisplaySecondaryValue(false);
|
||||
}
|
||||
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponChanged");
|
||||
m_hCurrentActiveWeapon = wpn;
|
||||
}
|
||||
}
|
||||
|
||||
void CHudAmmo::UpdateVehicleAmmo( C_BasePlayer *player, IClientVehicle *pVehicle )
|
||||
{
|
||||
m_hCurrentActiveWeapon = NULL;
|
||||
CBaseEntity *pVehicleEnt = pVehicle->GetVehicleEnt();
|
||||
|
||||
if ( !pVehicleEnt || pVehicle->GetPrimaryAmmoType() < 0 )
|
||||
{
|
||||
SetPaintEnabled(false);
|
||||
SetPaintBackgroundEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SetPaintEnabled(true);
|
||||
SetPaintBackgroundEnabled(true);
|
||||
|
||||
// get the ammo in our clip
|
||||
int ammo1 = pVehicle->GetPrimaryAmmoClip();
|
||||
int ammo2;
|
||||
if (ammo1 < 0)
|
||||
{
|
||||
// we don't use clip ammo, just use the total ammo count
|
||||
ammo1 = pVehicle->GetPrimaryAmmoCount();
|
||||
ammo2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we use clip ammo, so the second ammo is the total ammo
|
||||
ammo2 = pVehicle->GetPrimaryAmmoCount();
|
||||
}
|
||||
|
||||
if (pVehicleEnt == m_hCurrentVehicle)
|
||||
{
|
||||
// same weapon, just update counts
|
||||
SetAmmo(ammo1, true);
|
||||
SetAmmo2(ammo2, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// diferent weapon, change without triggering
|
||||
SetAmmo(ammo1, false);
|
||||
SetAmmo2(ammo2, false);
|
||||
|
||||
// update whether or not we show the total ammo display
|
||||
if (pVehicle->PrimaryAmmoUsesClips())
|
||||
{
|
||||
SetShouldDisplaySecondaryValue(true);
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesClips");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseClips");
|
||||
SetShouldDisplaySecondaryValue(false);
|
||||
}
|
||||
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponChanged");
|
||||
m_hCurrentVehicle = pVehicleEnt;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: called every frame to get ammo info from the weapon
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudAmmo::OnThink()
|
||||
{
|
||||
UpdateAmmoDisplays();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: updates the ammo display counts
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudAmmo::UpdateAmmoDisplays()
|
||||
{
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
IClientVehicle *pVehicle = player ? player->GetVehicle() : NULL;
|
||||
|
||||
if ( !pVehicle )
|
||||
{
|
||||
UpdatePlayerAmmo( player );
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateVehicleAmmo( player, pVehicle );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Updates ammo display
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudAmmo::SetAmmo(int ammo, bool playAnimation)
|
||||
{
|
||||
if (ammo != m_iAmmo)
|
||||
{
|
||||
if (ammo == 0)
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoEmpty");
|
||||
}
|
||||
else if (ammo < m_iAmmo)
|
||||
{
|
||||
// ammo has decreased
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoDecreased");
|
||||
}
|
||||
else
|
||||
{
|
||||
// ammunition has increased
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoIncreased");
|
||||
}
|
||||
|
||||
m_iAmmo = ammo;
|
||||
}
|
||||
|
||||
SetDisplayValue(ammo);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Updates 2nd ammo display
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudAmmo::SetAmmo2(int ammo2, bool playAnimation)
|
||||
{
|
||||
if (ammo2 != m_iAmmo2)
|
||||
{
|
||||
if (ammo2 == 0)
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Empty");
|
||||
}
|
||||
else if (ammo2 < m_iAmmo2)
|
||||
{
|
||||
// ammo has decreased
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Decreased");
|
||||
}
|
||||
else
|
||||
{
|
||||
// ammunition has increased
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("Ammo2Increased");
|
||||
}
|
||||
|
||||
m_iAmmo2 = ammo2;
|
||||
}
|
||||
|
||||
SetSecondaryValue(ammo2);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: We add an icon into the
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudAmmo::Paint( void )
|
||||
{
|
||||
BaseClass::Paint();
|
||||
|
||||
#ifndef HL2MP
|
||||
if ( m_hCurrentVehicle == NULL && m_iconPrimaryAmmo )
|
||||
{
|
||||
int nLabelHeight;
|
||||
int nLabelWidth;
|
||||
surface()->GetTextSize( m_hTextFont, m_LabelText, nLabelWidth, nLabelHeight );
|
||||
|
||||
// Figure out where we're going to put this
|
||||
int x = text_xpos + ( nLabelWidth - m_iconPrimaryAmmo->Width() ) / 2;
|
||||
int y = text_ypos - ( nLabelHeight + ( m_iconPrimaryAmmo->Height() / 2 ) );
|
||||
|
||||
m_iconPrimaryAmmo->DrawSelf( x, y, GetFgColor() );
|
||||
}
|
||||
#endif // HL2MP
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Displays the secondary ammunition level
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudSecondaryAmmo : public CHudNumericDisplay, public CHudElement
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudSecondaryAmmo, CHudNumericDisplay );
|
||||
|
||||
public:
|
||||
CHudSecondaryAmmo( const char *pElementName ) : BaseClass( NULL, "HudAmmoSecondary" ), CHudElement( pElementName )
|
||||
{
|
||||
m_iAmmo = -1;
|
||||
|
||||
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_WEAPONSELECTION | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
|
||||
}
|
||||
|
||||
void Init( void )
|
||||
{
|
||||
#ifndef HL2MP
|
||||
wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AMMO_ALT");
|
||||
if (tempString)
|
||||
{
|
||||
SetLabelText(tempString);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLabelText(L"ALT");
|
||||
}
|
||||
#endif // HL2MP
|
||||
}
|
||||
|
||||
void VidInit( void )
|
||||
{
|
||||
}
|
||||
|
||||
void SetAmmo( int ammo )
|
||||
{
|
||||
if (ammo != m_iAmmo)
|
||||
{
|
||||
if (ammo == 0)
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryEmpty");
|
||||
}
|
||||
else if (ammo < m_iAmmo)
|
||||
{
|
||||
// ammo has decreased
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryDecreased");
|
||||
}
|
||||
else
|
||||
{
|
||||
// ammunition has increased
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("AmmoSecondaryIncreased");
|
||||
}
|
||||
|
||||
m_iAmmo = ammo;
|
||||
}
|
||||
SetDisplayValue( ammo );
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
// hud reset, update ammo state
|
||||
BaseClass::Reset();
|
||||
m_iAmmo = 0;
|
||||
m_hCurrentActiveWeapon = NULL;
|
||||
SetAlpha( 0 );
|
||||
UpdateAmmoState();
|
||||
}
|
||||
|
||||
virtual void Paint( void )
|
||||
{
|
||||
BaseClass::Paint();
|
||||
|
||||
#ifndef HL2MP
|
||||
if ( m_iconSecondaryAmmo )
|
||||
{
|
||||
int nLabelHeight;
|
||||
int nLabelWidth;
|
||||
surface()->GetTextSize( m_hTextFont, m_LabelText, nLabelWidth, nLabelHeight );
|
||||
|
||||
// Figure out where we're going to put this
|
||||
int x = text_xpos + ( nLabelWidth - m_iconSecondaryAmmo->Width() ) / 2;
|
||||
int y = text_ypos - ( nLabelHeight + ( m_iconSecondaryAmmo->Height() / 2 ) );
|
||||
|
||||
m_iconSecondaryAmmo->DrawSelf( x, y, GetFgColor() );
|
||||
}
|
||||
#endif // HL2MP
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void OnThink()
|
||||
{
|
||||
// set whether or not the panel draws based on if we have a weapon that supports secondary ammo
|
||||
C_BaseCombatWeapon *wpn = GetActiveWeapon();
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
IClientVehicle *pVehicle = player ? player->GetVehicle() : NULL;
|
||||
if (!wpn || !player || pVehicle)
|
||||
{
|
||||
m_hCurrentActiveWeapon = NULL;
|
||||
SetPaintEnabled(false);
|
||||
SetPaintBackgroundEnabled(false);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPaintEnabled(true);
|
||||
SetPaintBackgroundEnabled(true);
|
||||
}
|
||||
|
||||
UpdateAmmoState();
|
||||
}
|
||||
|
||||
void UpdateAmmoState()
|
||||
{
|
||||
C_BaseCombatWeapon *wpn = GetActiveWeapon();
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
|
||||
if (player && wpn && wpn->UsesSecondaryAmmo())
|
||||
{
|
||||
SetAmmo(player->GetAmmoCount(wpn->GetSecondaryAmmoType()));
|
||||
}
|
||||
|
||||
if ( m_hCurrentActiveWeapon != wpn )
|
||||
{
|
||||
if ( wpn->UsesSecondaryAmmo() )
|
||||
{
|
||||
// we've changed to a weapon that uses secondary ammo
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponUsesSecondaryAmmo");
|
||||
}
|
||||
else
|
||||
{
|
||||
// we've changed away from a weapon that uses secondary ammo
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("WeaponDoesNotUseSecondaryAmmo");
|
||||
}
|
||||
m_hCurrentActiveWeapon = wpn;
|
||||
|
||||
// Get the icon we should be displaying
|
||||
m_iconSecondaryAmmo = gWR.GetAmmoIconFromWeapon( m_hCurrentActiveWeapon->GetSecondaryAmmoType() );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CHandle< C_BaseCombatWeapon > m_hCurrentActiveWeapon;
|
||||
CHudTexture *m_iconSecondaryAmmo;
|
||||
int m_iAmmo;
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHudSecondaryAmmo );
|
||||
|
||||
472
game/client/hl2/hud_autoaim.cpp
Normal file
472
game/client/hl2/hud_autoaim.cpp
Normal file
@@ -0,0 +1,472 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hudelement.h"
|
||||
#include "iclientmode.h"
|
||||
#include "c_basehlplayer.h"
|
||||
#include "view_scene.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "vgui_controls/AnimationController.h"
|
||||
#include "vgui_controls/Controls.h"
|
||||
#include "vgui_controls/Panel.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "iviewrender.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
ConVar hud_draw_active_reticle("hud_draw_active_reticle", "0" );
|
||||
ConVar hud_draw_fixed_reticle("hud_draw_fixed_reticle", "0", FCVAR_ARCHIVE );
|
||||
ConVar hud_autoaim_scale_icon( "hud_autoaim_scale_icon", "0" );
|
||||
ConVar hud_autoaim_method( "hud_autoaim_method", "1" );
|
||||
|
||||
ConVar hud_reticle_scale("hud_reticle_scale", "1.0" );
|
||||
ConVar hud_reticle_minalpha( "hud_reticle_minalpha", "125" );
|
||||
ConVar hud_reticle_maxalpha( "hud_reticle_maxalpha", "255" );
|
||||
ConVar hud_alpha_speed("hud_reticle_alpha_speed", "700" );
|
||||
ConVar hud_magnetism("hud_magnetism", "0.3" );
|
||||
|
||||
enum
|
||||
{
|
||||
AUTOAIM_METHOD_RETICLE = 1,
|
||||
AUTOAIM_METHOD_DRIFT,
|
||||
};
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
class CHUDAutoAim : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHUDAutoAim, vgui::Panel );
|
||||
public:
|
||||
CHUDAutoAim( const char *pElementName );
|
||||
virtual ~CHUDAutoAim( void );
|
||||
|
||||
void ApplySchemeSettings( IScheme *scheme );
|
||||
void Init( void );
|
||||
void VidInit( void );
|
||||
bool ShouldDraw( void );
|
||||
virtual void OnThink();
|
||||
virtual void Paint();
|
||||
|
||||
private:
|
||||
void ResetAlpha() { m_alpha = 0; }
|
||||
void ResetScale() { m_scale = 1.0f; }
|
||||
|
||||
void ResetPosition()
|
||||
{
|
||||
m_vecPos.x = ScreenWidth() / 2;
|
||||
m_vecPos.y = ScreenHeight() / 2;
|
||||
m_vecPos.z = 0;
|
||||
}
|
||||
|
||||
Vector m_vecPos;
|
||||
float m_alpha;
|
||||
float m_scale;
|
||||
|
||||
float m_alphaFixed; // alpha value for the fixed element.
|
||||
|
||||
int m_textureID_ActiveReticle;
|
||||
int m_textureID_FixedReticle;
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHUDAutoAim );
|
||||
|
||||
CHUDAutoAim::CHUDAutoAim( const char *pElementName ) :
|
||||
CHudElement( pElementName ), BaseClass( NULL, "HUDAutoAim" )
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
SetHiddenBits( HIDEHUD_CROSSHAIR );
|
||||
|
||||
m_textureID_ActiveReticle = -1;
|
||||
m_textureID_FixedReticle = -1;
|
||||
}
|
||||
|
||||
CHUDAutoAim::~CHUDAutoAim( void )
|
||||
{
|
||||
if ( vgui::surface() )
|
||||
{
|
||||
if ( m_textureID_ActiveReticle != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_textureID_ActiveReticle );
|
||||
m_textureID_ActiveReticle = -1;
|
||||
}
|
||||
|
||||
if ( m_textureID_FixedReticle != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_textureID_FixedReticle );
|
||||
m_textureID_FixedReticle = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CHUDAutoAim::ApplySchemeSettings( IScheme *scheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( scheme );
|
||||
|
||||
SetPaintBackgroundEnabled( false );
|
||||
}
|
||||
|
||||
void CHUDAutoAim::Init( void )
|
||||
{
|
||||
ResetPosition();
|
||||
ResetAlpha();
|
||||
ResetScale();
|
||||
}
|
||||
|
||||
void CHUDAutoAim::VidInit( void )
|
||||
{
|
||||
SetAlpha( 255 );
|
||||
Init();
|
||||
|
||||
if ( m_textureID_ActiveReticle == -1 )
|
||||
{
|
||||
m_textureID_ActiveReticle = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_textureID_ActiveReticle, "vgui/hud/autoaim", true, false );
|
||||
}
|
||||
|
||||
if ( m_textureID_FixedReticle == -1 )
|
||||
{
|
||||
m_textureID_FixedReticle = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_textureID_FixedReticle, "vgui/hud/xbox_reticle", true, false );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Save CPU cycles by letting the HUD system early cull
|
||||
// costly traversal. Called per frame, return true if thinking and
|
||||
// painting need to occur.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHUDAutoAim::ShouldDraw( void )
|
||||
{
|
||||
#ifndef HL1_CLIENT_DLL
|
||||
C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
|
||||
if ( pLocalPlayer )
|
||||
{
|
||||
if( !pLocalPlayer->m_HL2Local.m_bDisplayReticle )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ( (hud_draw_fixed_reticle.GetBool() || hud_draw_active_reticle.GetBool()) && CHudElement::ShouldDraw() && !engine->IsDrawingLoadingImage() );
|
||||
}
|
||||
|
||||
#define AUTOAIM_ALPHA_UP_SPEED 1000
|
||||
#define AUTOAIM_ALPHA_DOWN_SPEED 300
|
||||
#define AUTOAIM_MAX_ALPHA 120
|
||||
#define AUTOAIM_MAX_SCALE 1.0f
|
||||
#define AUTOAIM_MIN_SCALE 0.5f
|
||||
#define AUTOAIM_SCALE_SPEED 10.0f
|
||||
#define AUTOAIM_ONTARGET_CROSSHAIR_SPEED (ScreenWidth() / 3) // Can cross the whole screen in 3 seconds.
|
||||
#define AUTOAIM_OFFTARGET_CROSSHAIR_SPEED (ScreenWidth() / 4)
|
||||
|
||||
void CHUDAutoAim::OnThink()
|
||||
{
|
||||
int wide, tall;
|
||||
GetSize( wide, tall );
|
||||
|
||||
BaseClass::OnThink();
|
||||
|
||||
// Get the HL2 player
|
||||
C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
|
||||
if ( pLocalPlayer == NULL )
|
||||
{
|
||||
// Just turn the autoaim crosshair off.
|
||||
ResetPosition();
|
||||
ResetAlpha();
|
||||
ResetScale();
|
||||
|
||||
m_alphaFixed = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the autoaim target.
|
||||
CBaseEntity *pTarget = pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get();
|
||||
|
||||
// Fixed element stuff
|
||||
float flFixedAlphaGoal;
|
||||
|
||||
if( pTarget )
|
||||
{
|
||||
flFixedAlphaGoal = hud_reticle_maxalpha.GetFloat();
|
||||
}
|
||||
else
|
||||
{
|
||||
flFixedAlphaGoal = hud_reticle_minalpha.GetFloat();
|
||||
}
|
||||
|
||||
if( pLocalPlayer->m_HL2Local.m_bZooming || pLocalPlayer->m_HL2Local.m_bWeaponLowered )
|
||||
{
|
||||
flFixedAlphaGoal = 0.0f;
|
||||
}
|
||||
|
||||
m_alphaFixed = Approach( flFixedAlphaGoal, m_alphaFixed, (hud_alpha_speed.GetFloat() * gpGlobals->frametime) );
|
||||
|
||||
|
||||
switch( hud_autoaim_method.GetInt() )
|
||||
{
|
||||
case AUTOAIM_METHOD_RETICLE:
|
||||
{
|
||||
if( pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() && pLocalPlayer->m_HL2Local.m_bStickyAutoAim )
|
||||
{
|
||||
if( !pLocalPlayer->IsInAVehicle() )
|
||||
{
|
||||
Vector vecLook;
|
||||
pLocalPlayer->EyeVectors( &vecLook, NULL, NULL );
|
||||
|
||||
Vector vecMove = pLocalPlayer->GetAbsVelocity();
|
||||
float flSpeed = VectorNormalize( vecMove );
|
||||
float flDot = DotProduct( vecLook, vecMove );
|
||||
|
||||
if( flSpeed >= 100 && fabs(flDot) <= 0.707f )
|
||||
{
|
||||
QAngle viewangles;
|
||||
QAngle targetangles;
|
||||
QAngle delta;
|
||||
|
||||
engine->GetViewAngles( viewangles );
|
||||
|
||||
Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition();
|
||||
VectorNormalize(vecDir);
|
||||
VectorAngles( vecDir, targetangles );
|
||||
|
||||
float magnetism = hud_magnetism.GetFloat();
|
||||
|
||||
delta[0] = ApproachAngle( targetangles[0], viewangles[0], magnetism );
|
||||
delta[1] = ApproachAngle( targetangles[1], viewangles[1], magnetism );
|
||||
delta[2] = targetangles[2];
|
||||
|
||||
//viewangles[PITCH] = clamp( viewangles[ PITCH ], -cl_pitchup.GetFloat(), cl_pitchdown.GetFloat() );
|
||||
engine->SetViewAngles( delta );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool doScaling = hud_autoaim_scale_icon.GetBool();
|
||||
|
||||
// These are the X & Y coords of where the crosshair should be. Default to
|
||||
// returning to the center of the screen if there is no target.
|
||||
int goalx = ScreenWidth() / 2;
|
||||
int goaly = ScreenHeight() / 2;
|
||||
int goalalpha = 0;
|
||||
float goalscale = AUTOAIM_MIN_SCALE;
|
||||
float speed = AUTOAIM_OFFTARGET_CROSSHAIR_SPEED;
|
||||
|
||||
if( pTarget )
|
||||
{
|
||||
// Get the autoaim crosshair onto the target.
|
||||
Vector screen;
|
||||
|
||||
// Center the crosshair on the entity.
|
||||
if( doScaling )
|
||||
{
|
||||
// Put the crosshair over the center of the target.
|
||||
ScreenTransform( pTarget->WorldSpaceCenter(), screen );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Put the crosshair exactly where the player is aiming.
|
||||
ScreenTransform( pLocalPlayer->m_HL2Local.m_vecAutoAimPoint, screen );
|
||||
}
|
||||
|
||||
// Set Goal Position and speed.
|
||||
goalx += 0.5f * screen[0] * ScreenWidth() + 0.5f;
|
||||
goaly -= 0.5f * screen[1] * ScreenHeight() + 0.5f;
|
||||
speed = AUTOAIM_ONTARGET_CROSSHAIR_SPEED;
|
||||
|
||||
goalalpha = AUTOAIM_MAX_ALPHA;
|
||||
|
||||
if( doScaling )
|
||||
{
|
||||
// Scale the crosshair to envelope the entity's bounds on screen.
|
||||
Vector vecMins, vecMaxs;
|
||||
Vector vecScreenMins, vecScreenMaxs;
|
||||
|
||||
// Get mins and maxs in world space
|
||||
vecMins = pTarget->GetAbsOrigin() + pTarget->WorldAlignMins();
|
||||
vecMaxs = pTarget->GetAbsOrigin() + pTarget->WorldAlignMaxs();
|
||||
|
||||
// Project them to screen
|
||||
ScreenTransform( vecMins, vecScreenMins );
|
||||
ScreenTransform( vecMaxs, vecScreenMaxs );
|
||||
|
||||
vecScreenMins.y = (ScreenWidth()/2) - 0.5f * vecScreenMins.y * ScreenWidth() + 0.5f;
|
||||
vecScreenMaxs.y = (ScreenWidth()/2) - 0.5f * vecScreenMaxs.y * ScreenWidth() + 0.5f;
|
||||
|
||||
float screenSize = vecScreenMins.y - vecScreenMaxs.y;
|
||||
|
||||
// Set goal scale
|
||||
goalscale = screenSize / 64.0f; // 64 is the width of the crosshair art.
|
||||
}
|
||||
else
|
||||
{
|
||||
goalscale = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Now approach the goal, alpha, and scale
|
||||
Vector vecGoal( goalx, goaly, 0 );
|
||||
Vector vecDir = vecGoal - m_vecPos;
|
||||
float flDistRemaining = VectorNormalize( vecDir );
|
||||
m_vecPos += vecDir * min(flDistRemaining, (speed * gpGlobals->frametime) );
|
||||
|
||||
// Lerp and Clamp scale
|
||||
float scaleDelta = fabs( goalscale - m_scale );
|
||||
float scaleMove = MIN( AUTOAIM_SCALE_SPEED * gpGlobals->frametime, scaleDelta );
|
||||
if( m_scale < goalscale )
|
||||
{
|
||||
m_scale += scaleMove;
|
||||
}
|
||||
else if( m_scale > goalscale )
|
||||
{
|
||||
m_scale -= scaleMove;
|
||||
}
|
||||
if( m_scale > AUTOAIM_MAX_SCALE )
|
||||
{
|
||||
m_scale = AUTOAIM_MAX_SCALE;
|
||||
}
|
||||
else if( m_scale < AUTOAIM_MIN_SCALE )
|
||||
{
|
||||
m_scale = AUTOAIM_MIN_SCALE;
|
||||
}
|
||||
|
||||
if( goalalpha > m_alpha )
|
||||
{
|
||||
m_alpha += AUTOAIM_ALPHA_UP_SPEED * gpGlobals->frametime;
|
||||
}
|
||||
else if( goalalpha < m_alpha )
|
||||
{
|
||||
m_alpha -= AUTOAIM_ALPHA_DOWN_SPEED * gpGlobals->frametime;
|
||||
}
|
||||
|
||||
// Clamp alpha
|
||||
if( m_alpha < 0 )
|
||||
{
|
||||
m_alpha = 0;
|
||||
}
|
||||
else if( m_alpha > AUTOAIM_MAX_ALPHA )
|
||||
{
|
||||
m_alpha = AUTOAIM_MAX_ALPHA;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case AUTOAIM_METHOD_DRIFT:
|
||||
{
|
||||
if( pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() )
|
||||
{
|
||||
QAngle viewangles;
|
||||
|
||||
engine->GetViewAngles( viewangles );
|
||||
|
||||
Vector vecDir = pLocalPlayer->m_HL2Local.m_vecAutoAimPoint - pLocalPlayer->EyePosition();
|
||||
VectorNormalize(vecDir);
|
||||
|
||||
VectorAngles( vecDir, viewangles );
|
||||
|
||||
//viewangles[PITCH] = clamp( viewangles[ PITCH ], -cl_pitchup.GetFloat(), cl_pitchdown.GetFloat() );
|
||||
engine->SetViewAngles( viewangles );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CHUDAutoAim::Paint()
|
||||
{
|
||||
if( hud_draw_active_reticle.GetBool() )
|
||||
{
|
||||
int xCenter = m_vecPos.x;
|
||||
int yCenter = m_vecPos.y;
|
||||
|
||||
int width, height;
|
||||
float xMod, yMod;
|
||||
|
||||
vgui::surface()->DrawSetTexture( m_textureID_ActiveReticle );
|
||||
vgui::surface()->DrawSetColor( 255, 255, 255, m_alpha );
|
||||
vgui::surface()->DrawGetTextureSize( m_textureID_ActiveReticle, width, height );
|
||||
|
||||
float uv1 = 0.5f / width, uv2 = 1.0f - uv1;
|
||||
|
||||
vgui::Vertex_t vert[4];
|
||||
|
||||
Vector2D uv11( uv1, uv1 );
|
||||
Vector2D uv12( uv1, uv2 );
|
||||
Vector2D uv21( uv2, uv1 );
|
||||
Vector2D uv22( uv2, uv2 );
|
||||
|
||||
xMod = width;
|
||||
yMod = height;
|
||||
|
||||
xMod *= m_scale;
|
||||
yMod *= m_scale;
|
||||
|
||||
xMod /= 2;
|
||||
yMod /= 2;
|
||||
|
||||
vert[0].Init( Vector2D( xCenter + xMod, yCenter + yMod ), uv21 );
|
||||
vert[1].Init( Vector2D( xCenter - xMod, yCenter + yMod ), uv11 );
|
||||
vert[2].Init( Vector2D( xCenter - xMod, yCenter - yMod ), uv12 );
|
||||
vert[3].Init( Vector2D( xCenter + xMod, yCenter - yMod ), uv22 );
|
||||
vgui::surface()->DrawTexturedPolygon( 4, vert );
|
||||
}
|
||||
|
||||
if( hud_draw_fixed_reticle.GetBool() )
|
||||
{
|
||||
int width, height;
|
||||
float xMod, yMod;
|
||||
|
||||
vgui::surface()->DrawSetTexture( m_textureID_FixedReticle );
|
||||
vgui::surface()->DrawGetTextureSize( m_textureID_FixedReticle, width, height );
|
||||
|
||||
int xCenter = ScreenWidth() / 2;
|
||||
int yCenter = ScreenHeight() / 2;
|
||||
|
||||
vgui::Vertex_t vert[4];
|
||||
|
||||
Vector2D uv11( 0, 0 );
|
||||
Vector2D uv12( 0, 1 );
|
||||
Vector2D uv21( 1, 0 );
|
||||
Vector2D uv22( 1, 1 );
|
||||
|
||||
xMod = width;
|
||||
yMod = height;
|
||||
|
||||
xMod /= 2;
|
||||
yMod /= 2;
|
||||
|
||||
vert[0].Init( Vector2D( xCenter + xMod, yCenter + yMod ), uv21 );
|
||||
vert[1].Init( Vector2D( xCenter - xMod, yCenter + yMod ), uv11 );
|
||||
vert[2].Init( Vector2D( xCenter - xMod, yCenter - yMod ), uv12 );
|
||||
vert[3].Init( Vector2D( xCenter + xMod, yCenter - yMod ), uv22 );
|
||||
|
||||
Color clr;
|
||||
clr = gHUD.m_clrNormal;
|
||||
int r,g,b,a;
|
||||
clr.GetColor( r,g,b,a );
|
||||
|
||||
C_BaseHLPlayer *pLocalPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
|
||||
if( pLocalPlayer && pLocalPlayer->m_HL2Local.m_hAutoAimTarget.Get() )
|
||||
{
|
||||
r = 250;
|
||||
g = 138;
|
||||
b = 4;
|
||||
}
|
||||
|
||||
clr.SetColor( r,g,b,m_alphaFixed);
|
||||
|
||||
vgui::surface()->DrawSetColor( clr );
|
||||
vgui::surface()->DrawTexturedPolygon( 4, vert );
|
||||
}
|
||||
}
|
||||
147
game/client/hl2/hud_battery.cpp
Normal file
147
game/client/hl2/hud_battery.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
//
|
||||
// battery.cpp
|
||||
//
|
||||
// implementation of CHudBattery class
|
||||
//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hudelement.h"
|
||||
#include "hud_macros.h"
|
||||
#include "hud_numericdisplay.h"
|
||||
#include "iclientmode.h"
|
||||
|
||||
#include "vgui_controls/AnimationController.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define INIT_BAT -1
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Displays suit power (armor) on hud
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudBattery : public CHudNumericDisplay, public CHudElement
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudBattery, CHudNumericDisplay );
|
||||
|
||||
public:
|
||||
CHudBattery( const char *pElementName );
|
||||
void Init( void );
|
||||
void Reset( void );
|
||||
void VidInit( void );
|
||||
void OnThink( void );
|
||||
void MsgFunc_Battery(bf_read &msg );
|
||||
bool ShouldDraw();
|
||||
|
||||
private:
|
||||
int m_iBat;
|
||||
int m_iNewBat;
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHudBattery );
|
||||
DECLARE_HUD_MESSAGE( CHudBattery, Battery );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudBattery::CHudBattery( const char *pElementName ) : BaseClass(NULL, "HudSuit"), CHudElement( pElementName )
|
||||
{
|
||||
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_NEEDSUIT );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBattery::Init( void )
|
||||
{
|
||||
HOOK_HUD_MESSAGE( CHudBattery, Battery);
|
||||
Reset();
|
||||
m_iBat = INIT_BAT;
|
||||
m_iNewBat = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBattery::Reset( void )
|
||||
{
|
||||
SetLabelText(g_pVGuiLocalize->Find("#Valve_Hud_SUIT"));
|
||||
SetDisplayValue(m_iBat);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBattery::VidInit( void )
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Save CPU cycles by letting the HUD system early cull
|
||||
// costly traversal. Called per frame, return true if thinking and
|
||||
// painting need to occur.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHudBattery::ShouldDraw( void )
|
||||
{
|
||||
bool bNeedsDraw = ( m_iBat != m_iNewBat ) || ( GetAlpha() > 0 );
|
||||
|
||||
return ( bNeedsDraw && CHudElement::ShouldDraw() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBattery::OnThink( void )
|
||||
{
|
||||
if ( m_iBat == m_iNewBat )
|
||||
return;
|
||||
|
||||
if ( !m_iNewBat )
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitPowerZero");
|
||||
}
|
||||
else if ( m_iNewBat < m_iBat )
|
||||
{
|
||||
// battery power has decreased, so play the damaged animation
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitDamageTaken");
|
||||
|
||||
// play an extra animation if we're super low
|
||||
if ( m_iNewBat < 20 )
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitArmorLow");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// battery power has increased (if we had no previous armor, or if we just loaded the game, don't use alert state)
|
||||
if ( m_iBat == INIT_BAT || m_iBat == 0 || m_iNewBat >= 20)
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitPowerIncreasedAbove20");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitPowerIncreasedBelow20");
|
||||
}
|
||||
}
|
||||
|
||||
m_iBat = m_iNewBat;
|
||||
|
||||
SetDisplayValue(m_iBat);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBattery::MsgFunc_Battery( bf_read &msg )
|
||||
{
|
||||
m_iNewBat = msg.ReadShort();
|
||||
}
|
||||
34
game/client/hl2/hud_blood.cpp
Normal file
34
game/client/hl2/hud_blood.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
#include "c_te_effect_dispatch.h"
|
||||
#include "hud.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
void BloodSplatCallback( const CEffectData & data )
|
||||
{
|
||||
/*
|
||||
Msg("SPLAT!\n");
|
||||
|
||||
int x,y;
|
||||
|
||||
// Find our screen position to start from
|
||||
x = XRES(320);
|
||||
y = YRES(240);
|
||||
|
||||
// Draw the ammo label
|
||||
CHudTexture *pSplat = gHUD.GetIcon( "hud_blood1" );
|
||||
|
||||
// FIXME: This can only occur during vgui::Paint() stuff
|
||||
pSplat->DrawSelf( x, y, gHUD.m_clrNormal);
|
||||
*/
|
||||
}
|
||||
|
||||
DECLARE_CLIENT_EFFECT( "HudBloodSplat", BloodSplatCallback );
|
||||
197
game/client/hl2/hud_bonusprogress.cpp
Normal file
197
game/client/hl2/hud_bonusprogress.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
//
|
||||
// BonusProgress.cpp
|
||||
//
|
||||
// implementation of CHudBonusProgress class
|
||||
//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hud_macros.h"
|
||||
#include "view.h"
|
||||
|
||||
#include "iclientmode.h"
|
||||
|
||||
#include <KeyValues.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/ISystem.h>
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
|
||||
#include <vgui/ILocalize.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#include "hudelement.h"
|
||||
#include "hud_numericdisplay.h"
|
||||
|
||||
#include "convar.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define INIT_BONUS_PROGRESS -1
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: BonusProgress panel
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudBonusProgress : public CHudElement, public CHudNumericDisplay
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudBonusProgress, CHudNumericDisplay );
|
||||
|
||||
public:
|
||||
CHudBonusProgress( const char *pElementName );
|
||||
virtual void Init( void );
|
||||
virtual void VidInit( void );
|
||||
virtual void Reset( void );
|
||||
virtual void OnThink();
|
||||
|
||||
private:
|
||||
void SetChallengeLabel( void );
|
||||
|
||||
private:
|
||||
// old variables
|
||||
int m_iBonusProgress;
|
||||
|
||||
int m_iLastChallenge;
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHudBonusProgress );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudBonusProgress::CHudBonusProgress( const char *pElementName ) : CHudElement( pElementName ), CHudNumericDisplay(NULL, "HudBonusProgress")
|
||||
{
|
||||
SetHiddenBits( HIDEHUD_BONUS_PROGRESS );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBonusProgress::Init()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBonusProgress::Reset()
|
||||
{
|
||||
m_iBonusProgress = INIT_BONUS_PROGRESS;
|
||||
|
||||
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
|
||||
if ( local )
|
||||
m_iLastChallenge = local->GetBonusChallenge();
|
||||
|
||||
SetChallengeLabel();
|
||||
|
||||
SetDisplayValue(m_iBonusProgress);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBonusProgress::VidInit()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudBonusProgress::OnThink()
|
||||
{
|
||||
C_GameRules *pGameRules = GameRules();
|
||||
|
||||
if ( !pGameRules )
|
||||
{
|
||||
// Not ready to init!
|
||||
return;
|
||||
}
|
||||
|
||||
int newBonusProgress = 0;
|
||||
int iBonusChallenge = 0;
|
||||
|
||||
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !local )
|
||||
{
|
||||
// Not ready to init!
|
||||
return;
|
||||
}
|
||||
|
||||
// Never below zero
|
||||
newBonusProgress = MAX( local->GetBonusProgress(), 0 );
|
||||
iBonusChallenge = local->GetBonusChallenge();
|
||||
|
||||
// Only update the fade if we've changed bonusProgress
|
||||
if ( newBonusProgress == m_iBonusProgress && m_iLastChallenge == iBonusChallenge )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_iBonusProgress = newBonusProgress;
|
||||
|
||||
if ( m_iLastChallenge != iBonusChallenge )
|
||||
{
|
||||
m_iLastChallenge = iBonusChallenge;
|
||||
SetChallengeLabel();
|
||||
}
|
||||
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("BonusProgressFlash");
|
||||
|
||||
if ( pGameRules->IsBonusChallengeTimeBased() )
|
||||
{
|
||||
SetIsTime( true );
|
||||
SetIndent( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetIsTime( false );
|
||||
SetIndent( true );
|
||||
}
|
||||
|
||||
SetDisplayValue(m_iBonusProgress);
|
||||
}
|
||||
|
||||
void CHudBonusProgress::SetChallengeLabel( void )
|
||||
{
|
||||
// Blank for no challenge
|
||||
if ( m_iLastChallenge == 0 )
|
||||
{
|
||||
SetLabelText(L"");
|
||||
return;
|
||||
}
|
||||
|
||||
char szBonusTextName[] = "#Valve_Hud_BONUS_PROGRESS00";
|
||||
|
||||
int iStringLength = Q_strlen( szBonusTextName );
|
||||
|
||||
szBonusTextName[ iStringLength - 2 ] = ( m_iLastChallenge / 10 ) + '0';
|
||||
szBonusTextName[ iStringLength - 1 ] = ( m_iLastChallenge % 10 ) + '0';
|
||||
|
||||
wchar_t *tempString = g_pVGuiLocalize->Find(szBonusTextName);
|
||||
|
||||
if (tempString)
|
||||
{
|
||||
SetLabelText(tempString);
|
||||
return;
|
||||
}
|
||||
|
||||
// Couldn't find a special string for this challenge
|
||||
tempString = g_pVGuiLocalize->Find("#Valve_Hud_BONUS_PROGRESS");
|
||||
if (tempString)
|
||||
{
|
||||
SetLabelText(tempString);
|
||||
return;
|
||||
}
|
||||
|
||||
// Couldn't find any localizable string
|
||||
SetLabelText(L"BONUS");
|
||||
}
|
||||
735
game/client/hl2/hud_credits.cpp
Normal file
735
game/client/hl2/hud_credits.cpp
Normal file
@@ -0,0 +1,735 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hudelement.h"
|
||||
#include "hud_numericdisplay.h"
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include "hud.h"
|
||||
#include "hud_suitpower.h"
|
||||
#include "hud_macros.h"
|
||||
#include "iclientmode.h"
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/ILocalize.h>
|
||||
#include "KeyValues.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
struct creditname_t
|
||||
{
|
||||
char szCreditName[256];
|
||||
char szFontName[256];
|
||||
float flYPos;
|
||||
float flXPos;
|
||||
bool bActive;
|
||||
float flTime;
|
||||
float flTimeAdd;
|
||||
float flTimeStart;
|
||||
int iSlot;
|
||||
};
|
||||
|
||||
#define CREDITS_FILE "scripts/credits.txt"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGO_FADEIN = 0,
|
||||
LOGO_FADEHOLD,
|
||||
LOGO_FADEOUT,
|
||||
LOGO_FADEOFF,
|
||||
};
|
||||
|
||||
#define CREDITS_LOGO 1
|
||||
#define CREDITS_INTRO 2
|
||||
#define CREDITS_OUTRO 3
|
||||
|
||||
bool g_bRollingCredits = false;
|
||||
|
||||
int g_iCreditsPixelHeight = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shows the flashlight icon
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudCredits : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudCredits, vgui::Panel );
|
||||
|
||||
public:
|
||||
CHudCredits( const char *pElementName );
|
||||
virtual void Init( void );
|
||||
virtual void LevelShutdown( void );
|
||||
|
||||
int GetStringPixelWidth ( wchar_t *pString, vgui::HFont hFont );
|
||||
|
||||
void MsgFunc_CreditsMsg( bf_read &msg );
|
||||
void MsgFunc_LogoTimeMsg( bf_read &msg );
|
||||
|
||||
virtual bool ShouldDraw( void )
|
||||
{
|
||||
g_bRollingCredits = IsActive();
|
||||
|
||||
if ( g_bRollingCredits && m_iCreditsType == CREDITS_INTRO )
|
||||
g_bRollingCredits = false;
|
||||
|
||||
return IsActive();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void Paint();
|
||||
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
|
||||
|
||||
private:
|
||||
|
||||
void Clear();
|
||||
|
||||
void ReadNames( KeyValues *pKeyValue );
|
||||
void ReadParams( KeyValues *pKeyValue );
|
||||
void PrepareCredits( const char *pKeyName );
|
||||
void DrawOutroCreditsName( void );
|
||||
void DrawIntroCreditsName( void );
|
||||
void DrawLogo( void );
|
||||
|
||||
void PrepareLogo( float flTime );
|
||||
void PrepareOutroCredits( void );
|
||||
void PrepareIntroCredits( void );
|
||||
|
||||
float FadeBlend( float fadein, float fadeout, float hold, float localTime );
|
||||
|
||||
void PrepareLine( vgui::HFont hFont, char const *pchLine );
|
||||
|
||||
CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
|
||||
CPanelAnimationVar( Color, m_TextColor, "TextColor", "FgColor" );
|
||||
|
||||
CUtlVector<creditname_t> m_CreditsList;
|
||||
|
||||
float m_flScrollTime;
|
||||
float m_flSeparation;
|
||||
float m_flFadeTime;
|
||||
bool m_bLastOneInPlace;
|
||||
int m_Alpha;
|
||||
|
||||
int m_iCreditsType;
|
||||
int m_iLogoState;
|
||||
|
||||
float m_flFadeInTime;
|
||||
float m_flFadeHoldTime;
|
||||
float m_flFadeOutTime;
|
||||
float m_flNextStartTime;
|
||||
float m_flPauseBetweenWaves;
|
||||
|
||||
float m_flLogoTimeMod;
|
||||
float m_flLogoTime;
|
||||
float m_flLogoDesiredLength;
|
||||
|
||||
float m_flX;
|
||||
float m_flY;
|
||||
|
||||
char m_szLogo[256];
|
||||
char m_szLogo2[256];
|
||||
|
||||
Color m_cColor;
|
||||
};
|
||||
|
||||
|
||||
void CHudCredits::PrepareCredits( const char *pKeyName )
|
||||
{
|
||||
Clear();
|
||||
|
||||
KeyValues *pKV= new KeyValues( "CreditsFile" );
|
||||
if ( !pKV->LoadFromFile( filesystem, CREDITS_FILE, "MOD" ) )
|
||||
{
|
||||
pKV->deleteThis();
|
||||
|
||||
Assert( !"env_credits couldn't be initialized!" );
|
||||
return;
|
||||
}
|
||||
|
||||
KeyValues *pKVSubkey;
|
||||
if ( pKeyName )
|
||||
{
|
||||
pKVSubkey = pKV->FindKey( pKeyName );
|
||||
ReadNames( pKVSubkey );
|
||||
}
|
||||
|
||||
pKVSubkey = pKV->FindKey( "CreditsParams" );
|
||||
ReadParams( pKVSubkey );
|
||||
|
||||
pKV->deleteThis();
|
||||
}
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
DECLARE_HUDELEMENT( CHudCredits );
|
||||
DECLARE_HUD_MESSAGE( CHudCredits, CreditsMsg );
|
||||
DECLARE_HUD_MESSAGE( CHudCredits, LogoTimeMsg );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudCredits::CHudCredits( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudCredits" )
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
}
|
||||
|
||||
void CHudCredits::LevelShutdown()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CHudCredits::Clear( void )
|
||||
{
|
||||
SetActive( false );
|
||||
m_CreditsList.RemoveAll();
|
||||
m_bLastOneInPlace = false;
|
||||
m_Alpha = m_TextColor[3];
|
||||
m_iLogoState = LOGO_FADEOFF;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudCredits::Init()
|
||||
{
|
||||
HOOK_HUD_MESSAGE( CHudCredits, CreditsMsg );
|
||||
HOOK_HUD_MESSAGE( CHudCredits, LogoTimeMsg );
|
||||
SetActive( false );
|
||||
}
|
||||
|
||||
void CHudCredits::ReadNames( KeyValues *pKeyValue )
|
||||
{
|
||||
if ( pKeyValue == NULL )
|
||||
{
|
||||
Assert( !"CHudCredits couldn't be initialized!" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Now try and parse out each act busy anim
|
||||
KeyValues *pKVNames = pKeyValue->GetFirstSubKey();
|
||||
|
||||
while ( pKVNames )
|
||||
{
|
||||
creditname_t Credits;
|
||||
V_strcpy_safe( Credits.szCreditName, pKVNames->GetName() );
|
||||
V_strcpy_safe( Credits.szFontName, pKeyValue->GetString( Credits.szCreditName, "Default" ) );
|
||||
|
||||
m_CreditsList.AddToTail( Credits );
|
||||
pKVNames = pKVNames->GetNextKey();
|
||||
}
|
||||
}
|
||||
|
||||
void CHudCredits::ReadParams( KeyValues *pKeyValue )
|
||||
{
|
||||
if ( pKeyValue == NULL )
|
||||
{
|
||||
Assert( !"CHudCredits couldn't be initialized!" );
|
||||
return;
|
||||
}
|
||||
|
||||
m_flScrollTime = pKeyValue->GetFloat( "scrolltime", 57 );
|
||||
m_flSeparation = pKeyValue->GetFloat( "separation", 5 );
|
||||
|
||||
m_flFadeInTime = pKeyValue->GetFloat( "fadeintime", 1 );
|
||||
m_flFadeHoldTime = pKeyValue->GetFloat( "fadeholdtime", 3 );
|
||||
m_flFadeOutTime = pKeyValue->GetFloat( "fadeouttime", 2 );
|
||||
m_flNextStartTime = pKeyValue->GetFloat( "nextfadetime", 2 );
|
||||
m_flPauseBetweenWaves = pKeyValue->GetFloat( "pausebetweenwaves", 2 );
|
||||
|
||||
m_flLogoTimeMod = pKeyValue->GetFloat( "logotime", 2 );
|
||||
|
||||
m_flX = pKeyValue->GetFloat( "posx", 2 );
|
||||
m_flY = pKeyValue->GetFloat( "posy", 2 );
|
||||
|
||||
m_cColor = pKeyValue->GetColor( "color" );
|
||||
|
||||
Q_strncpy( m_szLogo, pKeyValue->GetString( "logo", "HALF-LIFE'" ), sizeof( m_szLogo ) );
|
||||
Q_strncpy( m_szLogo2, pKeyValue->GetString( "logo2", "" ), sizeof( m_szLogo2 ) );
|
||||
}
|
||||
|
||||
int CHudCredits::GetStringPixelWidth( wchar_t *pString, vgui::HFont hFont )
|
||||
{
|
||||
int iLength = 0;
|
||||
|
||||
for ( wchar_t *wch = pString; *wch != 0; wch++ )
|
||||
{
|
||||
iLength += surface()->GetCharacterWidth( hFont, *wch );
|
||||
}
|
||||
|
||||
return iLength;
|
||||
}
|
||||
|
||||
void CHudCredits::DrawOutroCreditsName( void )
|
||||
{
|
||||
if ( m_CreditsList.Count() == 0 )
|
||||
return;
|
||||
|
||||
// fill the screen
|
||||
int iWidth, iTall;
|
||||
GetHudSize(iWidth, iTall);
|
||||
SetSize( iWidth, iTall );
|
||||
|
||||
for ( int i = 0; i < m_CreditsList.Count(); i++ )
|
||||
{
|
||||
creditname_t *pCredit = &m_CreditsList[i];
|
||||
|
||||
if ( pCredit == NULL )
|
||||
continue;
|
||||
|
||||
vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
|
||||
vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
|
||||
|
||||
int iFontTall = surface()->GetFontTall ( m_hTFont );
|
||||
|
||||
if ( pCredit->flYPos < -iFontTall || pCredit->flYPos > iTall )
|
||||
{
|
||||
pCredit->bActive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCredit->bActive = true;
|
||||
}
|
||||
|
||||
Color cColor = m_TextColor;
|
||||
|
||||
//HACKHACK
|
||||
//Last one stays on screen and fades out
|
||||
if ( i == m_CreditsList.Count()-1 )
|
||||
{
|
||||
if ( m_bLastOneInPlace == false )
|
||||
{
|
||||
pCredit->flYPos -= gpGlobals->frametime * ( (float)g_iCreditsPixelHeight / m_flScrollTime );
|
||||
|
||||
if ( (int)pCredit->flYPos + ( iFontTall / 2 ) <= iTall / 2 )
|
||||
{
|
||||
m_bLastOneInPlace = true;
|
||||
|
||||
// 360 certification requires that we not hold a static image too long.
|
||||
m_flFadeTime = gpGlobals->curtime + ( IsConsole() ? 2.0f : 10.0f );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_flFadeTime <= gpGlobals->curtime )
|
||||
{
|
||||
if ( m_Alpha > 0 )
|
||||
{
|
||||
m_Alpha -= gpGlobals->frametime * ( m_flScrollTime * 2 );
|
||||
|
||||
if ( m_Alpha <= 0 )
|
||||
{
|
||||
pCredit->bActive = false;
|
||||
engine->ClientCmd( "creditsdone" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cColor[3] = MAX( 0, m_Alpha );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pCredit->flYPos -= gpGlobals->frametime * ( (float)g_iCreditsPixelHeight / m_flScrollTime );
|
||||
}
|
||||
|
||||
if ( pCredit->bActive == false )
|
||||
continue;
|
||||
|
||||
surface()->DrawSetTextFont( m_hTFont );
|
||||
surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
|
||||
|
||||
wchar_t unicode[256];
|
||||
|
||||
if ( pCredit->szCreditName[0] == '#' )
|
||||
{
|
||||
g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(pCredit->szCreditName), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( pCredit->szCreditName, unicode, sizeof( unicode ) );
|
||||
}
|
||||
|
||||
int iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
|
||||
|
||||
surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), pCredit->flYPos );
|
||||
surface()->DrawUnicodeString( unicode );
|
||||
}
|
||||
}
|
||||
|
||||
void CHudCredits::DrawLogo( void )
|
||||
{
|
||||
if( m_iLogoState == LOGO_FADEOFF )
|
||||
{
|
||||
SetActive( false );
|
||||
return;
|
||||
}
|
||||
|
||||
switch( m_iLogoState )
|
||||
{
|
||||
case LOGO_FADEIN:
|
||||
{
|
||||
float flDeltaTime = ( m_flFadeTime - gpGlobals->curtime );
|
||||
|
||||
m_Alpha = MAX( 0, RemapValClamped( flDeltaTime, 5.0f, 0, -128, 255 ) );
|
||||
|
||||
if ( flDeltaTime <= 0.0f )
|
||||
{
|
||||
m_iLogoState = LOGO_FADEHOLD;
|
||||
m_flFadeTime = gpGlobals->curtime + m_flLogoDesiredLength;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LOGO_FADEHOLD:
|
||||
{
|
||||
if ( m_flFadeTime <= gpGlobals->curtime )
|
||||
{
|
||||
m_iLogoState = LOGO_FADEOUT;
|
||||
m_flFadeTime = gpGlobals->curtime + 2.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LOGO_FADEOUT:
|
||||
{
|
||||
float flDeltaTime = ( m_flFadeTime - gpGlobals->curtime );
|
||||
|
||||
m_Alpha = RemapValClamped( flDeltaTime, 0.0f, 2.0f, 0, 255 );
|
||||
|
||||
if ( flDeltaTime <= 0.0f )
|
||||
{
|
||||
m_iLogoState = LOGO_FADEOFF;
|
||||
SetActive( false );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// fill the screen
|
||||
int iWidth, iTall;
|
||||
GetHudSize(iWidth, iTall);
|
||||
SetSize( iWidth, iTall );
|
||||
|
||||
char szLogoFont[64];
|
||||
|
||||
if ( IsXbox() )
|
||||
{
|
||||
Q_snprintf( szLogoFont, sizeof( szLogoFont ), "WeaponIcons_Small" );
|
||||
}
|
||||
else if ( hl2_episodic.GetBool() )
|
||||
{
|
||||
Q_snprintf( szLogoFont, sizeof( szLogoFont ), "ClientTitleFont" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( szLogoFont, sizeof( szLogoFont ), "WeaponIcons" );
|
||||
}
|
||||
|
||||
vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
|
||||
vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( szLogoFont );
|
||||
|
||||
int iFontTall = surface()->GetFontTall ( m_hTFont );
|
||||
|
||||
Color cColor = m_TextColor;
|
||||
cColor[3] = m_Alpha;
|
||||
|
||||
surface()->DrawSetTextFont( m_hTFont );
|
||||
surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
|
||||
|
||||
wchar_t unicode[256];
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( m_szLogo, unicode, sizeof( unicode ) );
|
||||
|
||||
int iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
|
||||
|
||||
surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), ( iTall / 2 ) - ( iFontTall / 2 ) );
|
||||
surface()->DrawUnicodeString( unicode );
|
||||
|
||||
if ( Q_strlen( m_szLogo2 ) > 0 )
|
||||
{
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( m_szLogo2, unicode, sizeof( unicode ) );
|
||||
|
||||
iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
|
||||
|
||||
surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), ( iTall / 2 ) + ( iFontTall / 2 ));
|
||||
surface()->DrawUnicodeString( unicode );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
float CHudCredits::FadeBlend( float fadein, float fadeout, float hold, float localTime )
|
||||
{
|
||||
float fadeTime = fadein + hold;
|
||||
float fadeBlend;
|
||||
|
||||
if ( localTime < 0 )
|
||||
return 0;
|
||||
|
||||
if ( localTime < fadein )
|
||||
{
|
||||
fadeBlend = 1 - ((fadein - localTime) / fadein);
|
||||
}
|
||||
else if ( localTime > fadeTime )
|
||||
{
|
||||
if ( fadeout > 0 )
|
||||
fadeBlend = 1 - ((localTime - fadeTime) / fadeout);
|
||||
else
|
||||
fadeBlend = 0;
|
||||
}
|
||||
else
|
||||
fadeBlend = 1;
|
||||
|
||||
if ( fadeBlend < 0 )
|
||||
fadeBlend = 0;
|
||||
|
||||
return fadeBlend;
|
||||
}
|
||||
|
||||
void CHudCredits::DrawIntroCreditsName( void )
|
||||
{
|
||||
if ( m_CreditsList.Count() == 0 )
|
||||
return;
|
||||
|
||||
// fill the screen
|
||||
int iWidth, iTall;
|
||||
GetHudSize(iWidth, iTall);
|
||||
SetSize( iWidth, iTall );
|
||||
|
||||
for ( int i = 0; i < m_CreditsList.Count(); i++ )
|
||||
{
|
||||
creditname_t *pCredit = &m_CreditsList[i];
|
||||
|
||||
if ( pCredit == NULL )
|
||||
continue;
|
||||
|
||||
if ( pCredit->bActive == false )
|
||||
continue;
|
||||
|
||||
vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
|
||||
vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName );
|
||||
|
||||
float localTime = gpGlobals->curtime - pCredit->flTimeStart;
|
||||
|
||||
surface()->DrawSetTextFont( m_hTFont );
|
||||
surface()->DrawSetTextColor( m_cColor[0], m_cColor[1], m_cColor[2], FadeBlend( m_flFadeInTime, m_flFadeOutTime, m_flFadeHoldTime + pCredit->flTimeAdd, localTime ) * m_cColor[3] );
|
||||
|
||||
wchar_t unicode[256];
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( pCredit->szCreditName, unicode, sizeof( unicode ) );
|
||||
|
||||
surface()->DrawSetTextPos( XRES( pCredit->flXPos ), YRES( pCredit->flYPos ) );
|
||||
surface()->DrawUnicodeString( unicode );
|
||||
|
||||
if ( m_flLogoTime > gpGlobals->curtime )
|
||||
continue;
|
||||
|
||||
if ( pCredit->flTime - m_flNextStartTime <= gpGlobals->curtime )
|
||||
{
|
||||
if ( m_CreditsList.IsValidIndex( i + 3 ) )
|
||||
{
|
||||
creditname_t *pNextCredits = &m_CreditsList[i + 3];
|
||||
|
||||
if ( pNextCredits && pNextCredits->flTime == 0.0f )
|
||||
{
|
||||
pNextCredits->bActive = true;
|
||||
|
||||
if ( i < 3 )
|
||||
{
|
||||
pNextCredits->flTimeAdd = ( i + 1.0f );
|
||||
pNextCredits->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime + pNextCredits->flTimeAdd;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNextCredits->flTimeAdd = m_flPauseBetweenWaves;
|
||||
pNextCredits->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime + pNextCredits->flTimeAdd;
|
||||
}
|
||||
|
||||
pNextCredits->flTimeStart = gpGlobals->curtime;
|
||||
|
||||
pNextCredits->iSlot = pCredit->iSlot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( pCredit->flTime <= gpGlobals->curtime )
|
||||
{
|
||||
pCredit->bActive = false;
|
||||
|
||||
if ( i == m_CreditsList.Count()-1 )
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CHudCredits::ApplySchemeSettings( IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
SetVisible( ShouldDraw() );
|
||||
|
||||
SetBgColor( Color(0, 0, 0, 0) );
|
||||
}
|
||||
|
||||
void CHudCredits::Paint()
|
||||
{
|
||||
if ( m_iCreditsType == CREDITS_LOGO )
|
||||
{
|
||||
DrawLogo();
|
||||
}
|
||||
else if ( m_iCreditsType == CREDITS_INTRO )
|
||||
{
|
||||
DrawIntroCreditsName();
|
||||
}
|
||||
else if ( m_iCreditsType == CREDITS_OUTRO )
|
||||
{
|
||||
DrawOutroCreditsName();
|
||||
}
|
||||
}
|
||||
|
||||
void CHudCredits::PrepareLogo( float flTime )
|
||||
{
|
||||
// Only showing the logo. Just load the CreditsParams section.
|
||||
PrepareCredits( NULL );
|
||||
|
||||
m_Alpha = 0;
|
||||
m_flLogoDesiredLength = flTime;
|
||||
m_flFadeTime = gpGlobals->curtime + 5.0f;
|
||||
m_iLogoState = LOGO_FADEIN;
|
||||
SetActive( true );
|
||||
}
|
||||
|
||||
void CHudCredits::PrepareLine( vgui::HFont hFont, char const *pchLine )
|
||||
{
|
||||
Assert( pchLine );
|
||||
|
||||
wchar_t unicode[256];
|
||||
|
||||
if ( pchLine[0] == '#' )
|
||||
{
|
||||
g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(pchLine), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( pchLine, unicode, sizeof( unicode ) );
|
||||
}
|
||||
|
||||
surface()->PrecacheFontCharacters( hFont, unicode );
|
||||
}
|
||||
|
||||
void CHudCredits::PrepareOutroCredits( void )
|
||||
{
|
||||
PrepareCredits( "OutroCreditsNames" );
|
||||
|
||||
if ( m_CreditsList.Count() == 0 )
|
||||
return;
|
||||
|
||||
// fill the screen
|
||||
int iWidth, iTall;
|
||||
GetHudSize(iWidth, iTall);
|
||||
SetSize( iWidth, iTall );
|
||||
|
||||
int iHeight = iTall;
|
||||
|
||||
for ( int i = 0; i < m_CreditsList.Count(); i++ )
|
||||
{
|
||||
creditname_t *pCredit = &m_CreditsList[i];
|
||||
|
||||
if ( pCredit == NULL )
|
||||
continue;
|
||||
|
||||
vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
|
||||
vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
|
||||
|
||||
pCredit->flYPos = iHeight;
|
||||
pCredit->bActive = false;
|
||||
|
||||
iHeight += surface()->GetFontTall ( m_hTFont ) + m_flSeparation;
|
||||
|
||||
PrepareLine( m_hTFont, pCredit->szCreditName );
|
||||
}
|
||||
|
||||
SetActive( true );
|
||||
|
||||
g_iCreditsPixelHeight = iHeight;
|
||||
}
|
||||
|
||||
void CHudCredits::PrepareIntroCredits( void )
|
||||
{
|
||||
PrepareCredits( "IntroCreditsNames" );
|
||||
|
||||
int iSlot = 0;
|
||||
|
||||
for ( int i = 0; i < m_CreditsList.Count(); i++ )
|
||||
{
|
||||
creditname_t *pCredit = &m_CreditsList[i];
|
||||
|
||||
if ( pCredit == NULL )
|
||||
continue;
|
||||
|
||||
vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
|
||||
vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName );
|
||||
|
||||
pCredit->flYPos = m_flY + ( iSlot * surface()->GetFontTall ( m_hTFont ) );
|
||||
pCredit->flXPos = m_flX;
|
||||
|
||||
if ( i < 3 )
|
||||
{
|
||||
pCredit->bActive = true;
|
||||
pCredit->iSlot = iSlot;
|
||||
pCredit->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime;
|
||||
pCredit->flTimeStart = gpGlobals->curtime;
|
||||
m_flLogoTime = pCredit->flTime + m_flLogoTimeMod;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCredit->bActive = false;
|
||||
pCredit->flTime = 0.0f;
|
||||
}
|
||||
|
||||
iSlot = ( iSlot + 1 ) % 3;
|
||||
|
||||
PrepareLine( m_hTFont, pCredit->szCreditName );
|
||||
}
|
||||
|
||||
SetActive( true );
|
||||
}
|
||||
|
||||
void CHudCredits::MsgFunc_CreditsMsg( bf_read &msg )
|
||||
{
|
||||
m_iCreditsType = msg.ReadByte();
|
||||
|
||||
switch ( m_iCreditsType )
|
||||
{
|
||||
case CREDITS_LOGO:
|
||||
{
|
||||
PrepareLogo( 5.0f );
|
||||
break;
|
||||
}
|
||||
case CREDITS_INTRO:
|
||||
{
|
||||
PrepareIntroCredits();
|
||||
break;
|
||||
}
|
||||
case CREDITS_OUTRO:
|
||||
{
|
||||
PrepareOutroCredits();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CHudCredits::MsgFunc_LogoTimeMsg( bf_read &msg )
|
||||
{
|
||||
m_iCreditsType = CREDITS_LOGO;
|
||||
PrepareLogo( msg.ReadFloat() );
|
||||
}
|
||||
|
||||
|
||||
461
game/client/hl2/hud_damageindicator.cpp
Normal file
461
game/client/hl2/hud_damageindicator.cpp
Normal file
@@ -0,0 +1,461 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "text_message.h"
|
||||
#include "hud_macros.h"
|
||||
#include "iclientmode.h"
|
||||
#include "view.h"
|
||||
#include <KeyValues.h>
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "IEffects.h"
|
||||
#include "hudelement.h"
|
||||
#include "clienteffectprecachesystem.h"
|
||||
#include "sourcevr/isourcevirtualreality.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: HDU Damage indication
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudDamageIndicator : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudDamageIndicator, vgui::Panel );
|
||||
|
||||
public:
|
||||
CHudDamageIndicator( const char *pElementName );
|
||||
void Init( void );
|
||||
void Reset( void );
|
||||
virtual bool ShouldDraw( void );
|
||||
|
||||
// Handler for our message
|
||||
void MsgFunc_Damage( bf_read &msg );
|
||||
|
||||
private:
|
||||
virtual void Paint();
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
|
||||
private:
|
||||
CPanelAnimationVarAliasType( float, m_flDmgX, "dmg_xpos", "10", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flDmgY, "dmg_ypos", "80", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flDmgWide, "dmg_wide", "30", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flDmgTall1, "dmg_tall1", "300", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flDmgTall2, "dmg_tall2", "240", "proportional_float" );
|
||||
|
||||
CPanelAnimationVar( Color, m_DmgColorLeft, "DmgColorLeft", "255 0 0 0" );
|
||||
CPanelAnimationVar( Color, m_DmgColorRight, "DmgColorRight", "255 0 0 0" );
|
||||
|
||||
CPanelAnimationVar( Color, m_DmgHighColorLeft, "DmgHighColorLeft", "255 0 0 0" );
|
||||
CPanelAnimationVar( Color, m_DmgHighColorRight, "DmgHighColorRight", "255 0 0 0" );
|
||||
|
||||
CPanelAnimationVar( Color, m_DmgFullscreenColor, "DmgFullscreenColor", "255 0 0 0" );
|
||||
|
||||
void DrawDamageIndicator(int side);
|
||||
void DrawFullscreenDamageIndicator();
|
||||
void GetDamagePosition( const Vector &vecDelta, float *flRotation );
|
||||
|
||||
CMaterialReference m_WhiteAdditiveMaterial;
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHudDamageIndicator );
|
||||
DECLARE_HUD_MESSAGE( CHudDamageIndicator, Damage );
|
||||
|
||||
enum
|
||||
{
|
||||
DAMAGE_ANY,
|
||||
DAMAGE_LOW,
|
||||
DAMAGE_HIGH,
|
||||
};
|
||||
|
||||
#define ANGLE_ANY 0.0f
|
||||
#define DMG_ANY 0
|
||||
|
||||
struct DamageAnimation_t
|
||||
{
|
||||
const char *name;
|
||||
int bitsDamage;
|
||||
float angleMinimum;
|
||||
float angleMaximum;
|
||||
int damage;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: List of damage animations, finds first that matches criteria
|
||||
//-----------------------------------------------------------------------------
|
||||
static DamageAnimation_t g_DamageAnimations[] =
|
||||
{
|
||||
{ "HudTakeDamageDrown", DMG_DROWN, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
|
||||
{ "HudTakeDamagePoison", DMG_POISON, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
|
||||
{ "HudTakeDamageBurn", DMG_BURN, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
|
||||
{ "HudTakeDamageRadiation", DMG_RADIATION, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
|
||||
{ "HudTakeDamageRadiation", DMG_ACID, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
|
||||
|
||||
{ "HudTakeDamageHighLeft", DMG_ANY, 45.0f, 135.0f, DAMAGE_HIGH },
|
||||
{ "HudTakeDamageHighRight", DMG_ANY, 225.0f, 315.0f, DAMAGE_HIGH },
|
||||
{ "HudTakeDamageHigh", DMG_ANY, ANGLE_ANY, ANGLE_ANY, DAMAGE_HIGH },
|
||||
|
||||
{ "HudTakeDamageLeft", DMG_ANY, 45.0f, 135.0f, DAMAGE_ANY },
|
||||
{ "HudTakeDamageRight", DMG_ANY, 225.0f, 315.0f, DAMAGE_ANY },
|
||||
{ "HudTakeDamageBehind", DMG_ANY, 135.0f, 225.0f, DAMAGE_ANY },
|
||||
|
||||
// fall through to front damage
|
||||
{ "HudTakeDamageFront", DMG_ANY, ANGLE_ANY, ANGLE_ANY, DAMAGE_ANY },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudDamageIndicator::CHudDamageIndicator( const char *pElementName ) : CHudElement( pElementName ), BaseClass(NULL, "HudDamageIndicator")
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
m_WhiteAdditiveMaterial.Init( "vgui/white_additive", TEXTURE_GROUP_VGUI );
|
||||
|
||||
SetHiddenBits( HIDEHUD_HEALTH );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudDamageIndicator::Reset( void )
|
||||
{
|
||||
m_DmgColorLeft[3] = 0;
|
||||
m_DmgColorRight[3] = 0;
|
||||
m_DmgHighColorLeft[3] = 0;
|
||||
m_DmgHighColorRight[3] = 0;
|
||||
m_DmgFullscreenColor[3] = 0;
|
||||
}
|
||||
|
||||
void CHudDamageIndicator::Init( void )
|
||||
{
|
||||
HOOK_HUD_MESSAGE( CHudDamageIndicator, Damage );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Save CPU cycles by letting the HUD system early cull
|
||||
// costly traversal. Called per frame, return true if thinking and
|
||||
// painting need to occur.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHudDamageIndicator::ShouldDraw( void )
|
||||
{
|
||||
bool bNeedsDraw = m_DmgColorLeft[3] ||
|
||||
m_DmgColorRight[3] ||
|
||||
m_DmgHighColorLeft[3] ||
|
||||
m_DmgHighColorRight[3] ||
|
||||
m_DmgFullscreenColor[3];
|
||||
|
||||
return ( bNeedsDraw && CHudElement::ShouldDraw() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draws a damage quad
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudDamageIndicator::DrawDamageIndicator(int side)
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_WhiteAdditiveMaterial );
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
|
||||
|
||||
int insetY = (m_flDmgTall1 - m_flDmgTall2) / 2;
|
||||
|
||||
int x1 = m_flDmgX;
|
||||
int x2 = m_flDmgX + m_flDmgWide;
|
||||
int y[4] = { (int)m_flDmgY, (int)(m_flDmgY + insetY), (int)(m_flDmgY + m_flDmgTall1 - insetY), (int)(m_flDmgY + m_flDmgTall1) };
|
||||
int alpha[4] = { 0, 1, 1, 0 };
|
||||
|
||||
// see if we're high damage
|
||||
bool bHighDamage = false;
|
||||
if ( m_DmgHighColorRight[3] > m_DmgColorRight[3] || m_DmgHighColorLeft[3] > m_DmgColorLeft[3] )
|
||||
{
|
||||
// make more of the screen be covered by damage
|
||||
x1 = GetWide() * 0.0f;
|
||||
x2 = GetWide() * 0.5f;
|
||||
y[0] = 0.0f;
|
||||
y[1] = 0.0f;
|
||||
y[2] = GetTall();
|
||||
y[3] = GetTall();
|
||||
alpha[0] = 1.0f;
|
||||
alpha[1] = 0.0f;
|
||||
alpha[2] = 0.0f;
|
||||
alpha[3] = 1.0f;
|
||||
bHighDamage = true;
|
||||
}
|
||||
|
||||
int r, g, b, a;
|
||||
if (side == 1)
|
||||
{
|
||||
if ( bHighDamage )
|
||||
{
|
||||
r = m_DmgHighColorRight[0], g = m_DmgHighColorRight[1], b = m_DmgHighColorRight[2], a = m_DmgHighColorRight[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
r = m_DmgColorRight[0], g = m_DmgColorRight[1], b = m_DmgColorRight[2], a = m_DmgColorRight[3];
|
||||
}
|
||||
|
||||
// realign x coords
|
||||
x1 = GetWide() - x1;
|
||||
x2 = GetWide() - x2;
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a * alpha[0]);
|
||||
meshBuilder.TexCoord2f( 0,0,0 );
|
||||
meshBuilder.Position3f( x1, y[0], 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a * alpha[3] );
|
||||
meshBuilder.TexCoord2f( 0,0,1 );
|
||||
meshBuilder.Position3f( x1, y[3], 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a * alpha[2] );
|
||||
meshBuilder.TexCoord2f( 0,1,1 );
|
||||
meshBuilder.Position3f( x2, y[2], 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a * alpha[1] );
|
||||
meshBuilder.TexCoord2f( 0,1,0 );
|
||||
meshBuilder.Position3f( x2, y[1], 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( bHighDamage )
|
||||
{
|
||||
r = m_DmgHighColorLeft[0], g = m_DmgHighColorLeft[1], b = m_DmgHighColorLeft[2], a = m_DmgHighColorLeft[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
r = m_DmgColorLeft[0], g = m_DmgColorLeft[1], b = m_DmgColorLeft[2], a = m_DmgColorLeft[3];
|
||||
}
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a * alpha[0] );
|
||||
meshBuilder.TexCoord2f( 0,0,0 );
|
||||
meshBuilder.Position3f( x1, y[0], 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a * alpha[1] );
|
||||
meshBuilder.TexCoord2f( 0,1,0 );
|
||||
meshBuilder.Position3f( x2, y[1], 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a * alpha[2] );
|
||||
meshBuilder.TexCoord2f( 0,1,1 );
|
||||
meshBuilder.Position3f( x2, y[2], 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a * alpha[3] );
|
||||
meshBuilder.TexCoord2f( 0,0,1 );
|
||||
meshBuilder.Position3f( x1, y[3], 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draws full screen damage fade
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudDamageIndicator::DrawFullscreenDamageIndicator()
|
||||
{
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_WhiteAdditiveMaterial );
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
|
||||
int r = m_DmgFullscreenColor[0], g = m_DmgFullscreenColor[1], b = m_DmgFullscreenColor[2], a = m_DmgFullscreenColor[3];
|
||||
|
||||
float wide = GetWide(), tall = GetTall();
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a );
|
||||
meshBuilder.TexCoord2f( 0,0,0 );
|
||||
meshBuilder.Position3f( 0.0f, 0.0f, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a );
|
||||
meshBuilder.TexCoord2f( 0,1,0 );
|
||||
meshBuilder.Position3f( wide, 0.0f, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a );
|
||||
meshBuilder.TexCoord2f( 0,1,1 );
|
||||
meshBuilder.Position3f( wide, tall, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.Color4ub( r, g, b, a );
|
||||
meshBuilder.TexCoord2f( 0,0,1 );
|
||||
meshBuilder.Position3f( 0.0f, tall, 0 );
|
||||
meshBuilder.AdvanceVertex();
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Paints the damage display
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudDamageIndicator::Paint()
|
||||
{
|
||||
// draw fullscreen damage indicators
|
||||
DrawFullscreenDamageIndicator();
|
||||
|
||||
// draw side damage indicators
|
||||
DrawDamageIndicator(0);
|
||||
DrawDamageIndicator(1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Message handler for Damage message
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudDamageIndicator::MsgFunc_Damage( bf_read &msg )
|
||||
{
|
||||
int armor = msg.ReadByte(); // armor
|
||||
int damageTaken = msg.ReadByte(); // health
|
||||
long bitsDamage = msg.ReadLong(); // damage bits
|
||||
|
||||
Vector vecFrom;
|
||||
|
||||
vecFrom.x = msg.ReadFloat();
|
||||
vecFrom.y = msg.ReadFloat();
|
||||
vecFrom.z = msg.ReadFloat();
|
||||
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
// player has just died, just run the dead damage animation
|
||||
if ( pPlayer->GetHealth() <= 0 )
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "HudPlayerDeath" );
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore damage without direction
|
||||
// this should never happen, unless it's drowning damage,
|
||||
// or the player is forcibly killed, handled above
|
||||
if ( vecFrom == vec3_origin && !(bitsDamage & DMG_DROWN))
|
||||
return;
|
||||
|
||||
Vector vecDelta = (vecFrom - MainViewOrigin());
|
||||
VectorNormalize( vecDelta );
|
||||
|
||||
int highDamage = DAMAGE_LOW;
|
||||
if ( damageTaken > 25 )
|
||||
{
|
||||
highDamage = DAMAGE_HIGH;
|
||||
}
|
||||
|
||||
// if we have no suit, all damage is high
|
||||
if ( !pPlayer->IsSuitEquipped() )
|
||||
{
|
||||
highDamage = DAMAGE_HIGH;
|
||||
}
|
||||
|
||||
if ( damageTaken > 0 || armor > 0 )
|
||||
{
|
||||
// see which quandrant the effect is in
|
||||
float angle;
|
||||
GetDamagePosition( vecDelta, &angle );
|
||||
|
||||
// see which effect to play
|
||||
DamageAnimation_t *dmgAnim = g_DamageAnimations;
|
||||
for ( ; dmgAnim->name != NULL; ++dmgAnim )
|
||||
{
|
||||
if ( dmgAnim->bitsDamage && !(bitsDamage & dmgAnim->bitsDamage) )
|
||||
continue;
|
||||
|
||||
if ( dmgAnim->angleMinimum && angle < dmgAnim->angleMinimum )
|
||||
continue;
|
||||
|
||||
if ( dmgAnim->angleMaximum && angle > dmgAnim->angleMaximum )
|
||||
continue;
|
||||
|
||||
if ( dmgAnim->damage && dmgAnim->damage != highDamage )
|
||||
continue;
|
||||
|
||||
// we have a match, break
|
||||
break;
|
||||
}
|
||||
|
||||
if ( dmgAnim->name )
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( dmgAnim->name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Convert a damage position in world units to the screen's units
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudDamageIndicator::GetDamagePosition( const Vector &vecDelta, float *flRotation )
|
||||
{
|
||||
float flRadius = 360.0f;
|
||||
|
||||
// Player Data
|
||||
Vector playerPosition = MainViewOrigin();
|
||||
QAngle playerAngles = MainViewAngles();
|
||||
|
||||
Vector forward, right, up(0,0,1);
|
||||
AngleVectors (playerAngles, &forward, NULL, NULL );
|
||||
forward.z = 0;
|
||||
VectorNormalize(forward);
|
||||
CrossProduct( up, forward, right );
|
||||
float front = DotProduct(vecDelta, forward);
|
||||
float side = DotProduct(vecDelta, right);
|
||||
float xpos = flRadius * -side;
|
||||
float ypos = flRadius * -front;
|
||||
|
||||
// Get the rotation (yaw)
|
||||
*flRotation = atan2(xpos, ypos) + M_PI;
|
||||
*flRotation *= 180 / M_PI;
|
||||
|
||||
float yawRadians = -(*flRotation) * M_PI / 180.0f;
|
||||
float ca = cos( yawRadians );
|
||||
float sa = sin( yawRadians );
|
||||
|
||||
// Rotate it around the circle
|
||||
xpos = (int)((GetWide() / 2) + (flRadius * sa));
|
||||
ypos = (int)((GetTall() / 2) - (flRadius * ca));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: hud scheme settings
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudDamageIndicator::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
SetPaintBackgroundEnabled(false);
|
||||
|
||||
int vx, vy, vw, vh;
|
||||
vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh );
|
||||
|
||||
SetForceStereoRenderToFrameBuffer( true );
|
||||
|
||||
if( UseVR() )
|
||||
{
|
||||
m_flDmgY = 0.125f * (float)vh;
|
||||
m_flDmgTall1 = 0.625f * (float)vh;
|
||||
m_flDmgTall2 = 0.4f * (float)vh;
|
||||
m_flDmgWide = 0.1f * (float)vw;
|
||||
}
|
||||
|
||||
SetSize(vw, vh);
|
||||
}
|
||||
190
game/client/hl2/hud_filmdemo.cpp
Normal file
190
game/client/hl2/hud_filmdemo.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//===========================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_baseentity.h"
|
||||
#include "hud.h"
|
||||
#include "hudelement.h"
|
||||
#include "clientmode.h"
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include <vgui/IScheme.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudFilmDemo : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudFilmDemo, vgui::Panel );
|
||||
public:
|
||||
CHudFilmDemo( const char *name );
|
||||
|
||||
// vgui overrides
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme );
|
||||
virtual void Paint( void );
|
||||
virtual bool ShouldDraw( void );
|
||||
|
||||
void SetFilmDemoActive( bool bActive );
|
||||
|
||||
void SetLeftStringID( const char *id );
|
||||
void SetRightStringID( const char *id );
|
||||
|
||||
private:
|
||||
bool m_bFilmDemoActive;
|
||||
|
||||
char m_pLeftStringID[ 256 ];
|
||||
char m_pRightStringID[ 256 ];
|
||||
|
||||
// Painting
|
||||
//CPanelAnimationVar( float, m_flAlphaOverride, "Alpha", "0" );
|
||||
CPanelAnimationVar( Color, m_BorderColor, "BorderColor", "0 0 0 255" );
|
||||
CPanelAnimationVar( Color, m_TextColor, "TextColor", "255 255 255 255" );
|
||||
CPanelAnimationVarAliasType( int, m_iBorderLeft, "BorderLeft", "8", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iBorderRight, "BorderRight", "8", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iBorderTop, "BorderTop", "8", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iBorderBottom, "BorderBottom", "48", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iBorderCenter, "BorderCenter", "8", "proportional_int" );
|
||||
|
||||
CPanelAnimationVarAliasType( int, m_iLeftY, "LeftTitleY", "440", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iRightY, "RightTitleY", "440", "proportional_int" );
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHudFilmDemo );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudFilmDemo::CHudFilmDemo( const char *name ) : vgui::Panel( NULL, "HudHDRDemo" ), CHudElement( name )
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
SetPaintBorderEnabled( false );
|
||||
SetPaintBackgroundEnabled( false );
|
||||
|
||||
m_bFilmDemoActive = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudFilmDemo::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
SetSize( ScreenWidth(), ScreenHeight() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudFilmDemo::Paint()
|
||||
{
|
||||
int x, y, wide, tall;
|
||||
GetBounds( x, y, wide, tall );
|
||||
|
||||
// Draw the borders
|
||||
vgui::surface()->DrawSetColor( m_BorderColor );
|
||||
vgui::surface()->DrawFilledRect( 0, 0, m_iBorderLeft, tall ); // Left
|
||||
vgui::surface()->DrawFilledRect( wide-m_iBorderRight, 0, wide, tall ); // Right
|
||||
vgui::surface()->DrawFilledRect( m_iBorderLeft, 0, wide-m_iBorderRight, m_iBorderTop ); // Top
|
||||
vgui::surface()->DrawFilledRect( m_iBorderLeft, tall-m_iBorderBottom, wide-m_iBorderRight, tall ); // Bottom
|
||||
vgui::surface()->DrawFilledRect( ((wide-m_iBorderCenter)/2), m_iBorderTop, ((wide+m_iBorderCenter)/2), tall-m_iBorderBottom ); // Center
|
||||
|
||||
// Get our scheme and font information
|
||||
vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
|
||||
vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "MenuTitle" );
|
||||
vgui::surface()->DrawSetTextFont( hFont );
|
||||
vgui::surface()->DrawSetTextColor( m_TextColor );
|
||||
|
||||
wchar_t *tempString = g_pVGuiLocalize->Find( m_pLeftStringID );
|
||||
if( tempString )
|
||||
{
|
||||
int iLength = 0;
|
||||
for ( wchar_t *wch = tempString; *wch != 0; wch++ )
|
||||
{
|
||||
iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
|
||||
}
|
||||
vgui::surface()->DrawSetTextPos( floor(wide * 0.25) - (iLength / 2), m_iLeftY );
|
||||
vgui::surface()->DrawPrintText( tempString, wcslen(tempString) );
|
||||
}
|
||||
|
||||
tempString = g_pVGuiLocalize->Find( m_pRightStringID );
|
||||
if( tempString )
|
||||
{
|
||||
int iLength = 0;
|
||||
for ( wchar_t *wch = tempString; *wch != 0; wch++ )
|
||||
{
|
||||
iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
|
||||
}
|
||||
vgui::surface()->DrawSetTextPos( ceil(wide * 0.75) - (iLength / 2), m_iRightY );
|
||||
vgui::surface()->DrawPrintText( tempString, wcslen(tempString) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHudFilmDemo::ShouldDraw()
|
||||
{
|
||||
return ( m_bFilmDemoActive ); //&& m_flAlphaOverride > 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bActive -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudFilmDemo::SetFilmDemoActive( bool bActive )
|
||||
{
|
||||
if ( bActive && !m_bFilmDemoActive )
|
||||
{
|
||||
ConVarRef hideHud( "hidehud" );
|
||||
hideHud.SetValue( 15 );
|
||||
}
|
||||
else if ( !bActive && m_bFilmDemoActive )
|
||||
{
|
||||
ConVarRef hideHud( "hidehud" );
|
||||
hideHud.SetValue( 0 );
|
||||
}
|
||||
|
||||
m_bFilmDemoActive = bActive;
|
||||
}
|
||||
|
||||
void CHudFilmDemo::SetLeftStringID( const char *id )
|
||||
{
|
||||
Q_strcpy( m_pLeftStringID, id );
|
||||
}
|
||||
|
||||
void CHudFilmDemo::SetRightStringID( const char *id )
|
||||
{
|
||||
Q_strcpy( m_pRightStringID, id );
|
||||
}
|
||||
|
||||
void EnableHUDFilmDemo( bool bEnable, const char *left_string_id, const char *right_string_id )
|
||||
{
|
||||
CHudFilmDemo *pHudDemo = (CHudFilmDemo*)GET_HUDELEMENT( CHudFilmDemo );
|
||||
if ( pHudDemo )
|
||||
{
|
||||
if( left_string_id )
|
||||
{
|
||||
pHudDemo->SetLeftStringID( left_string_id );
|
||||
}
|
||||
|
||||
if( right_string_id )
|
||||
{
|
||||
pHudDemo->SetRightStringID( right_string_id );
|
||||
}
|
||||
|
||||
pHudDemo->SetFilmDemoActive( bEnable );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
162
game/client/hl2/hud_flashlight.cpp
Normal file
162
game/client/hl2/hud_flashlight.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hudelement.h"
|
||||
#include "hud_numericdisplay.h"
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include "hud.h"
|
||||
#include "hud_suitpower.h"
|
||||
#include "hud_macros.h"
|
||||
#include "iclientmode.h"
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include "c_basehlplayer.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shows the flashlight icon
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudFlashlight : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudFlashlight, vgui::Panel );
|
||||
|
||||
public:
|
||||
CHudFlashlight( const char *pElementName );
|
||||
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
|
||||
|
||||
protected:
|
||||
virtual void Paint();
|
||||
|
||||
private:
|
||||
void SetFlashlightState( bool flashlightOn );
|
||||
void Reset( void );
|
||||
|
||||
bool m_bFlashlightOn;
|
||||
CPanelAnimationVar( vgui::HFont, m_hFont, "Font", "WeaponIconsSmall" );
|
||||
CPanelAnimationVarAliasType( float, m_IconX, "icon_xpos", "4", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_IconY, "icon_ypos", "4", "proportional_float" );
|
||||
|
||||
CPanelAnimationVarAliasType( float, m_flBarInsetX, "BarInsetX", "2", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flBarInsetY, "BarInsetY", "18", "proportional_float" );
|
||||
|
||||
CPanelAnimationVarAliasType( float, m_flBarWidth, "BarWidth", "28", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flBarHeight, "BarHeight", "2", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flBarChunkWidth, "BarChunkWidth", "2", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flBarChunkGap, "BarChunkGap", "2", "proportional_float" );
|
||||
};
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
DECLARE_HUDELEMENT( CHudFlashlight );
|
||||
#endif // HL2_EPISODIC
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudFlashlight::CHudFlashlight( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudFlashlight" )
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pScheme -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudFlashlight::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Start with our background off
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudFlashlight::Reset( void )
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "SuitFlashlightOn" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: data accessor
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudFlashlight::SetFlashlightState( bool flashlightOn )
|
||||
{
|
||||
if ( m_bFlashlightOn == flashlightOn )
|
||||
return;
|
||||
|
||||
m_bFlashlightOn = flashlightOn;
|
||||
}
|
||||
|
||||
#define WCHAR_FLASHLIGHT_ON 169
|
||||
#define WCHAR_FLASHLIGHT_OFF 174
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: draws the flashlight icon
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudFlashlight::Paint()
|
||||
{
|
||||
#ifdef HL2_EPISODIC
|
||||
C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
// Only paint if we're using the new flashlight code
|
||||
if ( pPlayer->m_HL2Local.m_flFlashBattery < 0.0f )
|
||||
{
|
||||
SetPaintBackgroundEnabled( false );
|
||||
return;
|
||||
}
|
||||
|
||||
bool bIsOn = pPlayer->IsEffectActive( EF_DIMLIGHT );
|
||||
SetFlashlightState( bIsOn );
|
||||
|
||||
// get bar chunks
|
||||
int chunkCount = m_flBarWidth / (m_flBarChunkWidth + m_flBarChunkGap);
|
||||
int enabledChunks = (int)((float)chunkCount * (pPlayer->m_HL2Local.m_flFlashBattery * 1.0f/100.0f) + 0.5f );
|
||||
|
||||
Color clrFlashlight;
|
||||
clrFlashlight = ( enabledChunks < ( chunkCount / 4 ) ) ? gHUD.m_clrCaution : gHUD.m_clrNormal;
|
||||
clrFlashlight[3] = ( bIsOn ) ? 255: 32;
|
||||
|
||||
// Pick the right character given our current state
|
||||
wchar_t pState = ( bIsOn ) ? WCHAR_FLASHLIGHT_ON : WCHAR_FLASHLIGHT_OFF;
|
||||
|
||||
surface()->DrawSetTextFont( m_hFont );
|
||||
surface()->DrawSetTextColor( clrFlashlight );
|
||||
surface()->DrawSetTextPos( m_IconX, m_IconY );
|
||||
surface()->DrawUnicodeChar( pState );
|
||||
|
||||
// Don't draw the progress bar is we're fully charged
|
||||
if ( bIsOn == false && chunkCount == enabledChunks )
|
||||
return;
|
||||
|
||||
// draw the suit power bar
|
||||
surface()->DrawSetColor( clrFlashlight );
|
||||
int xpos = m_flBarInsetX, ypos = m_flBarInsetY;
|
||||
for (int i = 0; i < enabledChunks; i++)
|
||||
{
|
||||
surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
|
||||
xpos += (m_flBarChunkWidth + m_flBarChunkGap);
|
||||
}
|
||||
|
||||
// Be even less transparent than we already are
|
||||
clrFlashlight[3] = clrFlashlight[3] / 8;
|
||||
|
||||
// draw the exhausted portion of the bar.
|
||||
surface()->DrawSetColor( clrFlashlight );
|
||||
for (int i = enabledChunks; i < chunkCount; i++)
|
||||
{
|
||||
surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
|
||||
xpos += (m_flBarChunkWidth + m_flBarChunkGap);
|
||||
}
|
||||
#endif // HL2_EPISODIC
|
||||
}
|
||||
174
game/client/hl2/hud_hdrdemo.cpp
Normal file
174
game/client/hl2/hud_hdrdemo.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "c_baseentity.h"
|
||||
#include "hud.h"
|
||||
#include "hudelement.h"
|
||||
#include "clientmode.h"
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include <vgui/IScheme.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/ILocalize.h>
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudHDRDemo : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudHDRDemo, vgui::Panel );
|
||||
public:
|
||||
CHudHDRDemo( const char *name );
|
||||
|
||||
// vgui overrides
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme );
|
||||
virtual void Paint( void );
|
||||
virtual bool ShouldDraw( void );
|
||||
|
||||
void SetHDRDemoActive( bool bActive );
|
||||
|
||||
private:
|
||||
bool m_bHDRDemoActive;
|
||||
|
||||
// Painting
|
||||
//CPanelAnimationVar( float, m_flAlphaOverride, "Alpha", "0" );
|
||||
CPanelAnimationVar( Color, m_BorderColor, "BorderColor", "0 0 0 255" );
|
||||
CPanelAnimationVar( Color, m_TextColor, "TextColor", "255 255 255 255" );
|
||||
CPanelAnimationVarAliasType( int, m_iBorderLeft, "BorderLeft", "8", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iBorderRight, "BorderRight", "8", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iBorderTop, "BorderTop", "8", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iBorderBottom, "BorderBottom", "8", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iBorderCenter, "BorderCenter", "8", "proportional_int" );
|
||||
|
||||
CPanelAnimationVarAliasType( int, m_iLeftY, "LeftTitleY", "8", "proportional_int" );
|
||||
CPanelAnimationVarAliasType( int, m_iRightY, "RightTitleY", "8", "proportional_int" );
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHudHDRDemo );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudHDRDemo::CHudHDRDemo( const char *name ) : vgui::Panel( NULL, "HudHDRDemo" ), CHudElement( name )
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
SetPaintBorderEnabled( false );
|
||||
SetPaintBackgroundEnabled( false );
|
||||
|
||||
m_bHDRDemoActive = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudHDRDemo::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
SetSize( ScreenWidth(), ScreenHeight() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudHDRDemo::Paint()
|
||||
{
|
||||
int x, y, wide, tall;
|
||||
GetBounds( x, y, wide, tall );
|
||||
|
||||
// Draw the borders
|
||||
vgui::surface()->DrawSetColor( m_BorderColor );
|
||||
vgui::surface()->DrawFilledRect( 0, 0, m_iBorderLeft, tall ); // Left
|
||||
vgui::surface()->DrawFilledRect( wide-m_iBorderRight, 0, wide, tall ); // Right
|
||||
vgui::surface()->DrawFilledRect( m_iBorderLeft, 0, wide-m_iBorderRight, m_iBorderTop ); // Top
|
||||
vgui::surface()->DrawFilledRect( m_iBorderLeft, tall-m_iBorderBottom, wide-m_iBorderRight, tall ); // Bottom
|
||||
vgui::surface()->DrawFilledRect( ((wide-m_iBorderCenter)/2), m_iBorderTop, ((wide+m_iBorderCenter)/2), tall-m_iBorderBottom ); // Center
|
||||
|
||||
// Get our scheme and font information
|
||||
vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
|
||||
vgui::HFont hFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "HDRDemoText" );
|
||||
vgui::surface()->DrawSetTextFont( hFont );
|
||||
vgui::surface()->DrawSetTextColor( m_TextColor );
|
||||
|
||||
// Left Title
|
||||
wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_HDRDEMO_LeftTitle");
|
||||
if (tempString)
|
||||
{
|
||||
int iLength = 0;
|
||||
for ( wchar_t *wch = tempString; *wch != 0; wch++ )
|
||||
{
|
||||
iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
|
||||
}
|
||||
vgui::surface()->DrawSetTextPos( floor(wide * 0.25) - (iLength / 2), m_iLeftY );
|
||||
vgui::surface()->DrawPrintText(tempString, wcslen(tempString));
|
||||
}
|
||||
|
||||
// Right Title
|
||||
tempString = g_pVGuiLocalize->Find("#Valve_HDRDEMO_RightTitle");
|
||||
if (tempString)
|
||||
{
|
||||
int iLength = 0;
|
||||
for ( wchar_t *wch = tempString; *wch != 0; wch++ )
|
||||
{
|
||||
iLength += vgui::surface()->GetCharacterWidth( hFont, *wch );
|
||||
}
|
||||
vgui::surface()->DrawSetTextPos( ceil(wide * 0.75) - (iLength / 2), m_iRightY );
|
||||
vgui::surface()->DrawPrintText(tempString, wcslen(tempString));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHudHDRDemo::ShouldDraw()
|
||||
{
|
||||
return (
|
||||
// no split screen hud if not hdr
|
||||
(g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE) &&
|
||||
m_bHDRDemoActive
|
||||
); //&& m_flAlphaOverride > 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : bActive -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudHDRDemo::SetHDRDemoActive( bool bActive )
|
||||
{
|
||||
if ( bActive && !m_bHDRDemoActive )
|
||||
{
|
||||
ConVarRef pHideHud( "hidehud" );
|
||||
pHideHud.SetValue( 15 );
|
||||
}
|
||||
else if ( !bActive && m_bHDRDemoActive )
|
||||
{
|
||||
ConVarRef pHideHud( "hidehud" );
|
||||
pHideHud.SetValue( 0 );
|
||||
}
|
||||
|
||||
m_bHDRDemoActive = bActive;
|
||||
}
|
||||
|
||||
//=======================================================================================================
|
||||
// CONVAR to toggle this hud element
|
||||
void mat_show_ab_hdr_hudelement_changed( IConVar *pConVar, const char *pOldString, float flOldValue )
|
||||
{
|
||||
CHudHDRDemo *pHudDemo = (CHudHDRDemo*)GET_HUDELEMENT( CHudHDRDemo );
|
||||
if ( pHudDemo )
|
||||
{
|
||||
ConVarRef var( pConVar );
|
||||
pHudDemo->SetHDRDemoActive( var.GetBool() );
|
||||
}
|
||||
}
|
||||
ConVar mat_show_ab_hdr_hudelement( "mat_show_ab_hdr_hudelement", "0", FCVAR_CHEAT, "HDR Demo HUD Element toggle.", mat_show_ab_hdr_hudelement_changed );
|
||||
170
game/client/hl2/hud_health.cpp
Normal file
170
game/client/hl2/hud_health.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
//
|
||||
// Health.cpp
|
||||
//
|
||||
// implementation of CHudHealth class
|
||||
//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hud_macros.h"
|
||||
#include "view.h"
|
||||
|
||||
#include "iclientmode.h"
|
||||
|
||||
#include <KeyValues.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/ISystem.h>
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
|
||||
#include <vgui/ILocalize.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#include "hudelement.h"
|
||||
#include "hud_numericdisplay.h"
|
||||
|
||||
#include "convar.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define INIT_HEALTH -1
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Health panel
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudHealth : public CHudElement, public CHudNumericDisplay
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudHealth, CHudNumericDisplay );
|
||||
|
||||
public:
|
||||
CHudHealth( const char *pElementName );
|
||||
virtual void Init( void );
|
||||
virtual void VidInit( void );
|
||||
virtual void Reset( void );
|
||||
virtual void OnThink();
|
||||
void MsgFunc_Damage( bf_read &msg );
|
||||
|
||||
private:
|
||||
// old variables
|
||||
int m_iHealth;
|
||||
|
||||
int m_bitsDamage;
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHudHealth );
|
||||
DECLARE_HUD_MESSAGE( CHudHealth, Damage );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudHealth::CHudHealth( const char *pElementName ) : CHudElement( pElementName ), CHudNumericDisplay(NULL, "HudHealth")
|
||||
{
|
||||
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudHealth::Init()
|
||||
{
|
||||
HOOK_HUD_MESSAGE( CHudHealth, Damage );
|
||||
Reset();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudHealth::Reset()
|
||||
{
|
||||
m_iHealth = INIT_HEALTH;
|
||||
m_bitsDamage = 0;
|
||||
|
||||
wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_HEALTH");
|
||||
|
||||
if (tempString)
|
||||
{
|
||||
SetLabelText(tempString);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLabelText(L"HEALTH");
|
||||
}
|
||||
SetDisplayValue(m_iHealth);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudHealth::VidInit()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudHealth::OnThink()
|
||||
{
|
||||
int newHealth = 0;
|
||||
C_BasePlayer *local = C_BasePlayer::GetLocalPlayer();
|
||||
if ( local )
|
||||
{
|
||||
// Never below zero
|
||||
newHealth = MAX( local->GetHealth(), 0 );
|
||||
}
|
||||
|
||||
// Only update the fade if we've changed health
|
||||
if ( newHealth == m_iHealth )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_iHealth = newHealth;
|
||||
|
||||
if ( m_iHealth >= 20 )
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthIncreasedAbove20");
|
||||
}
|
||||
else if ( m_iHealth > 0 )
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthIncreasedBelow20");
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthLow");
|
||||
}
|
||||
|
||||
SetDisplayValue(m_iHealth);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudHealth::MsgFunc_Damage( bf_read &msg )
|
||||
{
|
||||
|
||||
int armor = msg.ReadByte(); // armor
|
||||
int damageTaken = msg.ReadByte(); // health
|
||||
long bitsDamage = msg.ReadLong(); // damage bits
|
||||
bitsDamage; // variable still sent but not used
|
||||
|
||||
Vector vecFrom;
|
||||
|
||||
vecFrom.x = msg.ReadBitCoord();
|
||||
vecFrom.y = msg.ReadBitCoord();
|
||||
vecFrom.z = msg.ReadBitCoord();
|
||||
|
||||
// Actually took damage?
|
||||
if ( damageTaken > 0 || armor > 0 )
|
||||
{
|
||||
if ( damageTaken > 0 )
|
||||
{
|
||||
// start the animation
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("HealthDamageTaken");
|
||||
}
|
||||
}
|
||||
}
|
||||
319
game/client/hl2/hud_locator.cpp
Normal file
319
game/client/hl2/hud_locator.cpp
Normal file
@@ -0,0 +1,319 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Hud locator element, helps direct the player to objects in the world
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hudelement.h"
|
||||
#include "hud_numericdisplay.h"
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include "hud.h"
|
||||
#include "hud_suitpower.h"
|
||||
#include "hud_macros.h"
|
||||
#include "iclientmode.h"
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include "c_basehlplayer.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define LOCATOR_MATERIAL_JALOPY "vgui/icons/icon_jalopy"
|
||||
#define LOCATOR_MATERIAL_BIG_TICK "vgui/icons/tick_long"
|
||||
#define LOCATOR_MATERIAL_SMALL_TICK "vgui/icons/tick_short"
|
||||
|
||||
ConVar hud_locator_alpha( "hud_locator_alpha", "230" );
|
||||
ConVar hud_locator_fov("hud_locator_fov", "350" );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shows positions of objects relative to the player.
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudLocator : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudLocator, vgui::Panel );
|
||||
|
||||
public:
|
||||
CHudLocator( const char *pElementName );
|
||||
virtual ~CHudLocator( void );
|
||||
|
||||
virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
|
||||
void VidInit( void );
|
||||
bool ShouldDraw();
|
||||
|
||||
protected:
|
||||
void FillRect( int x, int y, int w, int h );
|
||||
float LocatorXPositionForYawDiff( float yawDiff );
|
||||
void DrawGraduations( float flYawPlayerFacing );
|
||||
virtual void Paint();
|
||||
|
||||
private:
|
||||
void Reset( void );
|
||||
|
||||
int m_textureID_IconJalopy;
|
||||
int m_textureID_IconBigTick;
|
||||
int m_textureID_IconSmallTick;
|
||||
|
||||
Vector m_vecLocation;
|
||||
};
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
#ifdef HL2_EPISODIC
|
||||
DECLARE_HUDELEMENT( CHudLocator );
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudLocator::CHudLocator( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudLocator" )
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
|
||||
|
||||
m_textureID_IconJalopy = -1;
|
||||
m_textureID_IconSmallTick = -1;
|
||||
m_textureID_IconBigTick = -1;
|
||||
}
|
||||
|
||||
CHudLocator::~CHudLocator( void )
|
||||
{
|
||||
if ( vgui::surface() )
|
||||
{
|
||||
if ( m_textureID_IconJalopy != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_textureID_IconJalopy );
|
||||
m_textureID_IconJalopy = -1;
|
||||
}
|
||||
|
||||
if ( m_textureID_IconSmallTick != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_textureID_IconSmallTick );
|
||||
m_textureID_IconSmallTick = -1;
|
||||
}
|
||||
|
||||
if ( m_textureID_IconBigTick != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_textureID_IconBigTick );
|
||||
m_textureID_IconBigTick = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *pScheme -
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudLocator::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudLocator::VidInit( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHudLocator::ShouldDraw( void )
|
||||
{
|
||||
C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
if( pPlayer->GetVehicle() )
|
||||
return false;
|
||||
|
||||
if( pPlayer->m_HL2Local.m_vecLocatorOrigin == vec3_invalid )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Start with our background off
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudLocator::Reset( void )
|
||||
{
|
||||
m_vecLocation = Vector( 0, 0, 0 );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Make it a bit more convenient to do a filled rect.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudLocator::FillRect( int x, int y, int w, int h )
|
||||
{
|
||||
int panel_x, panel_y, panel_w, panel_h;
|
||||
GetBounds( panel_x, panel_y, panel_w, panel_h );
|
||||
vgui::surface()->DrawFilledRect( x, y, x+w, y+h );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
float CHudLocator::LocatorXPositionForYawDiff( float yawDiff )
|
||||
{
|
||||
float fov = hud_locator_fov.GetFloat() / 2;
|
||||
float remappedAngle = RemapVal( yawDiff, -fov, fov, -90, 90 );
|
||||
float cosine = sin(DEG2RAD(remappedAngle));
|
||||
int element_wide = GetWide();
|
||||
|
||||
float position = (element_wide>>1) + ((element_wide>>1) * cosine);
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Draw the tickmarks on the locator
|
||||
//-----------------------------------------------------------------------------
|
||||
#define NUM_GRADUATIONS 16.0f
|
||||
void CHudLocator::DrawGraduations( float flYawPlayerFacing )
|
||||
{
|
||||
int icon_wide, icon_tall;
|
||||
int xPos, yPos;
|
||||
float fov = hud_locator_fov.GetFloat() / 2;
|
||||
|
||||
if( m_textureID_IconBigTick == -1 )
|
||||
{
|
||||
m_textureID_IconBigTick = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_textureID_IconBigTick, LOCATOR_MATERIAL_BIG_TICK, true, false );
|
||||
}
|
||||
|
||||
if( m_textureID_IconSmallTick == -1 )
|
||||
{
|
||||
m_textureID_IconSmallTick = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_textureID_IconSmallTick, LOCATOR_MATERIAL_SMALL_TICK, true, false );
|
||||
}
|
||||
|
||||
int element_tall = GetTall(); // Height of the VGUI element
|
||||
|
||||
surface()->DrawSetColor( 255, 255, 255, 255 );
|
||||
|
||||
// Tick Icons
|
||||
|
||||
float angleStep = 360.0f / NUM_GRADUATIONS;
|
||||
bool tallLine = true;
|
||||
|
||||
for( float angle = -180 ; angle <= 180 ; angle += angleStep )
|
||||
{
|
||||
yPos = (element_tall>>1);
|
||||
|
||||
if( tallLine )
|
||||
{
|
||||
vgui::surface()->DrawSetTexture( m_textureID_IconBigTick );
|
||||
vgui::surface()->DrawGetTextureSize( m_textureID_IconBigTick, icon_wide, icon_tall );
|
||||
tallLine = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vgui::surface()->DrawSetTexture( m_textureID_IconSmallTick );
|
||||
vgui::surface()->DrawGetTextureSize( m_textureID_IconSmallTick, icon_wide, icon_tall );
|
||||
tallLine = true;
|
||||
}
|
||||
|
||||
float flDiff = UTIL_AngleDiff( flYawPlayerFacing, angle );
|
||||
|
||||
if( fabs(flDiff) > fov )
|
||||
continue;
|
||||
|
||||
float xPosition = LocatorXPositionForYawDiff( flDiff );
|
||||
|
||||
xPos = (int)xPosition;
|
||||
xPos -= (icon_wide>>1);
|
||||
|
||||
vgui::surface()->DrawTexturedRect(xPos, yPos, xPos+icon_wide, yPos+icon_tall);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: draws the locator icons on the VGUI element.
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudLocator::Paint()
|
||||
{
|
||||
#ifdef HL2_EPISODIC
|
||||
|
||||
if( m_textureID_IconJalopy == -1 )
|
||||
{
|
||||
m_textureID_IconJalopy = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_textureID_IconJalopy, LOCATOR_MATERIAL_JALOPY, true, false );
|
||||
}
|
||||
|
||||
int alpha = hud_locator_alpha.GetInt();
|
||||
|
||||
SetAlpha( alpha );
|
||||
|
||||
C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
if( pPlayer->m_HL2Local.m_vecLocatorOrigin == vec3_origin )
|
||||
return;
|
||||
|
||||
int element_tall = GetTall(); // Height of the VGUI element
|
||||
|
||||
float fov = (hud_locator_fov.GetFloat()) / 2.0f;
|
||||
|
||||
// Compute the relative position of objects we're tracking
|
||||
// We'll need the player's yaw for comparison.
|
||||
float flYawPlayerForward = pPlayer->EyeAngles().y;
|
||||
|
||||
// Copy this value out of the member variable in case we decide to expand this
|
||||
// feature later and want to iterate some kind of list.
|
||||
Vector vecLocation = pPlayer->m_HL2Local.m_vecLocatorOrigin;
|
||||
|
||||
Vector vecToLocation = vecLocation - pPlayer->GetAbsOrigin();
|
||||
QAngle locationAngles;
|
||||
|
||||
VectorAngles( vecToLocation, locationAngles );
|
||||
float yawDiff = UTIL_AngleDiff( flYawPlayerForward, locationAngles.y );
|
||||
bool bObjectInFOV = (yawDiff > -fov && yawDiff < fov);
|
||||
|
||||
// Draw the icons!
|
||||
int icon_wide, icon_tall;
|
||||
int xPos, yPos;
|
||||
surface()->DrawSetColor( 255, 255, 255, 255 );
|
||||
|
||||
DrawGraduations( flYawPlayerForward );
|
||||
|
||||
if( bObjectInFOV )
|
||||
{
|
||||
// The object's location maps to a valid position along the tape, so draw an icon.
|
||||
float tapePosition = LocatorXPositionForYawDiff(yawDiff);
|
||||
|
||||
// derive a scale for the locator icon
|
||||
yawDiff = fabs(yawDiff);
|
||||
float scale = 1.0f;
|
||||
scale = RemapValClamped( yawDiff, (fov/4), fov, 1.0f, 0.25f );
|
||||
|
||||
vgui::surface()->DrawSetTexture( m_textureID_IconJalopy );
|
||||
vgui::surface()->DrawGetTextureSize( m_textureID_IconJalopy, icon_wide, icon_tall );
|
||||
|
||||
float flIconWide = ((float)element_tall * 1.25f);
|
||||
float flIconTall = ((float)element_tall * 1.25f);
|
||||
|
||||
// Scale the icon as desired...
|
||||
|
||||
// Put back into ints
|
||||
icon_wide = (int)flIconWide;
|
||||
icon_tall = (int)flIconTall;
|
||||
|
||||
icon_wide *= scale;
|
||||
|
||||
//Msg("yawDiff:%f xPos:%d scale:%f\n", yawDiff, xPos, scale );
|
||||
|
||||
// Center the icon around its position.
|
||||
xPos = (int)tapePosition;
|
||||
xPos -= (icon_wide >> 1);
|
||||
yPos = (element_tall>>1) - (icon_tall >> 1);
|
||||
|
||||
//Msg("Drawing at %f %f\n", x, y );
|
||||
vgui::surface()->DrawTexturedRect(xPos, yPos, xPos+icon_wide, yPos+icon_tall);
|
||||
}
|
||||
|
||||
#endif // HL2_EPISODIC
|
||||
}
|
||||
|
||||
|
||||
155
game/client/hl2/hud_poisondamageindicator.cpp
Normal file
155
game/client/hl2/hud_poisondamageindicator.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "text_message.h"
|
||||
#include "hud_macros.h"
|
||||
#include "iclientmode.h"
|
||||
#include "view.h"
|
||||
#include "KeyValues.h"
|
||||
#include "vgui_controls/AnimationController.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "IEffects.h"
|
||||
#include "hudelement.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: HDU Damage indication
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudPoisonDamageIndicator : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudPoisonDamageIndicator, vgui::Panel );
|
||||
|
||||
public:
|
||||
CHudPoisonDamageIndicator( const char *pElementName );
|
||||
void Reset( void );
|
||||
virtual bool ShouldDraw( void );
|
||||
|
||||
private:
|
||||
virtual void OnThink();
|
||||
virtual void Paint();
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||
|
||||
private:
|
||||
CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
|
||||
CPanelAnimationVar( Color, m_TextColor, "TextColor", "FgColor" );
|
||||
CPanelAnimationVarAliasType( float, text_xpos, "text_xpos", "8", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, text_ypos, "text_ypos", "8", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, text_ygap, "text_ygap", "14", "proportional_float" );
|
||||
|
||||
bool m_bDamageIndicatorVisible;
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHudPoisonDamageIndicator );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudPoisonDamageIndicator::CHudPoisonDamageIndicator( const char *pElementName ) : CHudElement( pElementName ), BaseClass(NULL, "HudPoisonDamageIndicator")
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudPoisonDamageIndicator::Reset( void )
|
||||
{
|
||||
SetAlpha( 0 );
|
||||
m_bDamageIndicatorVisible = false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Save CPU cycles by letting the HUD system early cull
|
||||
// costly traversal. Called per frame, return true if thinking and
|
||||
// painting need to occur.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHudPoisonDamageIndicator::ShouldDraw( void )
|
||||
{
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
bool bNeedsDraw = ( ( pPlayer->IsPoisoned() != m_bDamageIndicatorVisible ) || ( GetAlpha() > 0 ) );
|
||||
|
||||
return ( bNeedsDraw && CHudElement::ShouldDraw() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: updates poison damage
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudPoisonDamageIndicator::OnThink()
|
||||
{
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
// update poison damage indicator
|
||||
bool bShouldIndicatorBeVisible = pPlayer->IsPoisoned();
|
||||
if (bShouldIndicatorBeVisible == m_bDamageIndicatorVisible)
|
||||
return;
|
||||
|
||||
// state change
|
||||
m_bDamageIndicatorVisible = bShouldIndicatorBeVisible;
|
||||
|
||||
if (m_bDamageIndicatorVisible)
|
||||
{
|
||||
SetVisible(true);
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "PoisonDamageTaken" );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "PoisonDamageCured" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Paints the damage display
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudPoisonDamageIndicator::Paint()
|
||||
{
|
||||
// draw the text
|
||||
surface()->DrawSetTextFont( m_hTextFont );
|
||||
surface()->DrawSetTextColor( m_TextColor );
|
||||
surface()->DrawSetTextPos(text_xpos, text_ypos);
|
||||
int ypos = text_ypos;
|
||||
|
||||
const wchar_t *labelText = g_pVGuiLocalize->Find("Valve_HudPoisonDamage");
|
||||
Assert( labelText );
|
||||
for (const wchar_t *wch = labelText; wch && *wch != 0; wch++)
|
||||
{
|
||||
if (*wch == '\n')
|
||||
{
|
||||
ypos += text_ygap;
|
||||
surface()->DrawSetTextPos(text_xpos, ypos);
|
||||
}
|
||||
else
|
||||
{
|
||||
surface()->DrawUnicodeChar(*wch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: hud scheme settings
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudPoisonDamageIndicator::ApplySchemeSettings(vgui::IScheme *pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
}
|
||||
408
game/client/hl2/hud_quickinfo.cpp
Normal file
408
game/client/hl2/hud_quickinfo.cpp
Normal file
@@ -0,0 +1,408 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hudelement.h"
|
||||
#include "iclientmode.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "vgui_controls/AnimationController.h"
|
||||
#include "vgui_controls/Controls.h"
|
||||
#include "vgui_controls/Panel.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "../hud_crosshair.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
|
||||
#ifdef SIXENSE
|
||||
#include "sixense/in_sixense.h"
|
||||
#include "view.h"
|
||||
int ScreenTransform( const Vector& point, Vector& screen );
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define HEALTH_WARNING_THRESHOLD 25
|
||||
|
||||
static ConVar hud_quickinfo( "hud_quickinfo", "1", FCVAR_ARCHIVE );
|
||||
|
||||
extern ConVar crosshair;
|
||||
|
||||
#define QUICKINFO_EVENT_DURATION 1.0f
|
||||
#define QUICKINFO_BRIGHTNESS_FULL 255
|
||||
#define QUICKINFO_BRIGHTNESS_DIM 64
|
||||
#define QUICKINFO_FADE_IN_TIME 0.5f
|
||||
#define QUICKINFO_FADE_OUT_TIME 2.0f
|
||||
|
||||
/*
|
||||
==================================================
|
||||
CHUDQuickInfo
|
||||
==================================================
|
||||
*/
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
class CHUDQuickInfo : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHUDQuickInfo, vgui::Panel );
|
||||
public:
|
||||
CHUDQuickInfo( const char *pElementName );
|
||||
void Init( void );
|
||||
void VidInit( void );
|
||||
bool ShouldDraw( void );
|
||||
virtual void OnThink();
|
||||
virtual void Paint();
|
||||
|
||||
virtual void ApplySchemeSettings( IScheme *scheme );
|
||||
private:
|
||||
|
||||
void DrawWarning( int x, int y, CHudTexture *icon, float &time );
|
||||
void UpdateEventTime( void );
|
||||
bool EventTimeElapsed( void );
|
||||
|
||||
int m_lastAmmo;
|
||||
int m_lastHealth;
|
||||
|
||||
float m_ammoFade;
|
||||
float m_healthFade;
|
||||
|
||||
bool m_warnAmmo;
|
||||
bool m_warnHealth;
|
||||
|
||||
bool m_bFadedOut;
|
||||
|
||||
bool m_bDimmed; // Whether or not we are dimmed down
|
||||
float m_flLastEventTime; // Last active event (controls dimmed state)
|
||||
|
||||
CHudTexture *m_icon_c;
|
||||
|
||||
CHudTexture *m_icon_rbn; // right bracket
|
||||
CHudTexture *m_icon_lbn; // left bracket
|
||||
|
||||
CHudTexture *m_icon_rb; // right bracket, full
|
||||
CHudTexture *m_icon_lb; // left bracket, full
|
||||
CHudTexture *m_icon_rbe; // right bracket, empty
|
||||
CHudTexture *m_icon_lbe; // left bracket, empty
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHUDQuickInfo );
|
||||
|
||||
CHUDQuickInfo::CHUDQuickInfo( const char *pElementName ) :
|
||||
CHudElement( pElementName ), BaseClass( NULL, "HUDQuickInfo" )
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
SetHiddenBits( HIDEHUD_CROSSHAIR );
|
||||
}
|
||||
|
||||
void CHUDQuickInfo::ApplySchemeSettings( IScheme *scheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( scheme );
|
||||
|
||||
SetPaintBackgroundEnabled( false );
|
||||
SetForceStereoRenderToFrameBuffer( true );
|
||||
}
|
||||
|
||||
|
||||
void CHUDQuickInfo::Init( void )
|
||||
{
|
||||
m_ammoFade = 0.0f;
|
||||
m_healthFade = 0.0f;
|
||||
|
||||
m_lastAmmo = 0;
|
||||
m_lastHealth = 100;
|
||||
|
||||
m_warnAmmo = false;
|
||||
m_warnHealth = false;
|
||||
|
||||
m_bFadedOut = false;
|
||||
m_bDimmed = false;
|
||||
m_flLastEventTime = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
void CHUDQuickInfo::VidInit( void )
|
||||
{
|
||||
Init();
|
||||
|
||||
m_icon_c = gHUD.GetIcon( "crosshair" );
|
||||
m_icon_rb = gHUD.GetIcon( "crosshair_right_full" );
|
||||
m_icon_lb = gHUD.GetIcon( "crosshair_left_full" );
|
||||
m_icon_rbe = gHUD.GetIcon( "crosshair_right_empty" );
|
||||
m_icon_lbe = gHUD.GetIcon( "crosshair_left_empty" );
|
||||
m_icon_rbn = gHUD.GetIcon( "crosshair_right" );
|
||||
m_icon_lbn = gHUD.GetIcon( "crosshair_left" );
|
||||
}
|
||||
|
||||
|
||||
void CHUDQuickInfo::DrawWarning( int x, int y, CHudTexture *icon, float &time )
|
||||
{
|
||||
float scale = (int)( fabs(sin(gpGlobals->curtime*8.0f)) * 128.0);
|
||||
|
||||
// Only fade out at the low point of our blink
|
||||
if ( time <= (gpGlobals->frametime * 200.0f) )
|
||||
{
|
||||
if ( scale < 40 )
|
||||
{
|
||||
time = 0.0f;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Counteract the offset below to survive another frame
|
||||
time += (gpGlobals->frametime * 200.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// Update our time
|
||||
time -= (gpGlobals->frametime * 200.0f);
|
||||
Color caution = gHUD.m_clrCaution;
|
||||
caution[3] = scale * 255;
|
||||
|
||||
icon->DrawSelf( x, y, caution );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Save CPU cycles by letting the HUD system early cull
|
||||
// costly traversal. Called per frame, return true if thinking and
|
||||
// painting need to occur.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHUDQuickInfo::ShouldDraw( void )
|
||||
{
|
||||
if ( !m_icon_c || !m_icon_rb || !m_icon_rbe || !m_icon_lb || !m_icon_lbe )
|
||||
return false;
|
||||
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
if ( player == NULL )
|
||||
return false;
|
||||
|
||||
if ( !crosshair.GetBool() && !IsX360() )
|
||||
return false;
|
||||
|
||||
return ( CHudElement::ShouldDraw() && !engine->IsDrawingLoadingImage() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Checks if the hud element needs to fade out
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHUDQuickInfo::OnThink()
|
||||
{
|
||||
BaseClass::OnThink();
|
||||
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
if ( player == NULL )
|
||||
return;
|
||||
|
||||
// see if we should fade in/out
|
||||
bool bFadeOut = player->IsZoomed();
|
||||
|
||||
// check if the state has changed
|
||||
if ( m_bFadedOut != bFadeOut )
|
||||
{
|
||||
m_bFadedOut = bFadeOut;
|
||||
|
||||
m_bDimmed = false;
|
||||
|
||||
if ( bFadeOut )
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", 0.0f, 0.0f, 0.25f, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", QUICKINFO_BRIGHTNESS_FULL, 0.0f, QUICKINFO_FADE_IN_TIME, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
}
|
||||
}
|
||||
else if ( !m_bFadedOut )
|
||||
{
|
||||
// If we're dormant, fade out
|
||||
if ( EventTimeElapsed() )
|
||||
{
|
||||
if ( !m_bDimmed )
|
||||
{
|
||||
m_bDimmed = true;
|
||||
g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", QUICKINFO_BRIGHTNESS_DIM, 0.0f, QUICKINFO_FADE_OUT_TIME, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
}
|
||||
}
|
||||
else if ( m_bDimmed )
|
||||
{
|
||||
// Fade back up, we're active
|
||||
m_bDimmed = false;
|
||||
g_pClientMode->GetViewportAnimationController()->RunAnimationCommand( this, "Alpha", QUICKINFO_BRIGHTNESS_FULL, 0.0f, QUICKINFO_FADE_IN_TIME, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CHUDQuickInfo::Paint()
|
||||
{
|
||||
C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
|
||||
if ( player == NULL )
|
||||
return;
|
||||
|
||||
C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
|
||||
if ( pWeapon == NULL )
|
||||
return;
|
||||
|
||||
float fX, fY;
|
||||
bool bBehindCamera = false;
|
||||
CHudCrosshair::GetDrawPosition( &fX, &fY, &bBehindCamera );
|
||||
|
||||
// if the crosshair is behind the camera, don't draw it
|
||||
if( bBehindCamera )
|
||||
return;
|
||||
|
||||
int xCenter = (int)fX;
|
||||
int yCenter = (int)fY - m_icon_lb->Height() / 2;
|
||||
|
||||
float scalar = 138.0f/255.0f;
|
||||
|
||||
// Check our health for a warning
|
||||
int health = player->GetHealth();
|
||||
if ( health != m_lastHealth )
|
||||
{
|
||||
UpdateEventTime();
|
||||
m_lastHealth = health;
|
||||
|
||||
if ( health <= HEALTH_WARNING_THRESHOLD )
|
||||
{
|
||||
if ( m_warnHealth == false )
|
||||
{
|
||||
m_healthFade = 255;
|
||||
m_warnHealth = true;
|
||||
|
||||
CLocalPlayerFilter filter;
|
||||
C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HUDQuickInfo.LowHealth" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_warnHealth = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check our ammo for a warning
|
||||
int ammo = pWeapon->Clip1();
|
||||
if ( ammo != m_lastAmmo )
|
||||
{
|
||||
UpdateEventTime();
|
||||
m_lastAmmo = ammo;
|
||||
|
||||
// Find how far through the current clip we are
|
||||
float ammoPerc = (float) ammo / (float) pWeapon->GetMaxClip1();
|
||||
|
||||
// Warn if we're below a certain percentage of our clip's size
|
||||
if (( pWeapon->GetMaxClip1() > 1 ) && ( ammoPerc <= ( 1.0f - CLIP_PERC_THRESHOLD )))
|
||||
{
|
||||
if ( m_warnAmmo == false )
|
||||
{
|
||||
m_ammoFade = 255;
|
||||
m_warnAmmo = true;
|
||||
|
||||
CLocalPlayerFilter filter;
|
||||
C_BaseEntity::EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "HUDQuickInfo.LowAmmo" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_warnAmmo = false;
|
||||
}
|
||||
}
|
||||
|
||||
Color clrNormal = gHUD.m_clrNormal;
|
||||
clrNormal[3] = 255 * scalar;
|
||||
m_icon_c->DrawSelf( xCenter, yCenter, clrNormal );
|
||||
|
||||
if( IsX360() )
|
||||
{
|
||||
// Because the fixed reticle draws on half-texels, this rather unsightly hack really helps
|
||||
// center the appearance of the quickinfo on 360 displays.
|
||||
xCenter += 1;
|
||||
}
|
||||
|
||||
if ( !hud_quickinfo.GetInt() )
|
||||
return;
|
||||
|
||||
int sinScale = (int)( fabs(sin(gpGlobals->curtime*8.0f)) * 128.0f );
|
||||
|
||||
// Update our health
|
||||
if ( m_healthFade > 0.0f )
|
||||
{
|
||||
DrawWarning( xCenter - (m_icon_lb->Width() * 2), yCenter, m_icon_lb, m_healthFade );
|
||||
}
|
||||
else
|
||||
{
|
||||
float healthPerc = (float) health / 100.0f;
|
||||
healthPerc = clamp( healthPerc, 0.0f, 1.0f );
|
||||
|
||||
Color healthColor = m_warnHealth ? gHUD.m_clrCaution : gHUD.m_clrNormal;
|
||||
|
||||
if ( m_warnHealth )
|
||||
{
|
||||
healthColor[3] = 255 * sinScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
healthColor[3] = 255 * scalar;
|
||||
}
|
||||
|
||||
gHUD.DrawIconProgressBar( xCenter - (m_icon_lb->Width() * 2), yCenter, m_icon_lb, m_icon_lbe, ( 1.0f - healthPerc ), healthColor, CHud::HUDPB_VERTICAL );
|
||||
}
|
||||
|
||||
// Update our ammo
|
||||
if ( m_ammoFade > 0.0f )
|
||||
{
|
||||
DrawWarning( xCenter + m_icon_rb->Width(), yCenter, m_icon_rb, m_ammoFade );
|
||||
}
|
||||
else
|
||||
{
|
||||
float ammoPerc;
|
||||
|
||||
if ( pWeapon->GetMaxClip1() <= 0 )
|
||||
{
|
||||
ammoPerc = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
ammoPerc = 1.0f - ( (float) ammo / (float) pWeapon->GetMaxClip1() );
|
||||
ammoPerc = clamp( ammoPerc, 0.0f, 1.0f );
|
||||
}
|
||||
|
||||
Color ammoColor = m_warnAmmo ? gHUD.m_clrCaution : gHUD.m_clrNormal;
|
||||
|
||||
if ( m_warnAmmo )
|
||||
{
|
||||
ammoColor[3] = 255 * sinScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
ammoColor[3] = 255 * scalar;
|
||||
}
|
||||
|
||||
gHUD.DrawIconProgressBar( xCenter + m_icon_rb->Width(), yCenter, m_icon_rb, m_icon_rbe, ammoPerc, ammoColor, CHud::HUDPB_VERTICAL );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHUDQuickInfo::UpdateEventTime( void )
|
||||
{
|
||||
m_flLastEventTime = gpGlobals->curtime;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHUDQuickInfo::EventTimeElapsed( void )
|
||||
{
|
||||
if (( gpGlobals->curtime - m_flLastEventTime ) > QUICKINFO_EVENT_DURATION )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
587
game/client/hl2/hud_radar.cpp
Normal file
587
game/client/hl2/hud_radar.cpp
Normal file
@@ -0,0 +1,587 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include <vgui/ISurface.h>
|
||||
#include "hud_numericdisplay.h"
|
||||
#include "iclientmode.h"
|
||||
#include <coordsize.h>
|
||||
#include "hud_macros.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "mapoverview.h"
|
||||
#include "hud_radar.h"
|
||||
#include "iclientvehicle.h"
|
||||
|
||||
#define RADAR_DOT_NORMAL 0
|
||||
#define RADAR_IGNORE_Z (1<<6) //always draw this item as if it was at the same Z as the player
|
||||
#define RADAR_MAX_GHOST_ALPHA 25
|
||||
|
||||
DECLARE_VGUI_SCREEN_FACTORY( CHudRadar, "jalopy_radar_panel" );
|
||||
|
||||
#define RADAR_PANEL_MATERIAL "vgui/screens/radar"
|
||||
#define RADAR_CONTACT_LAMBDA_MATERIAL "vgui/icons/icon_lambda" // Lambda cache
|
||||
#define RADAR_CONTACT_BUSTER_MATERIAL "vgui/icons/icon_buster" // Striderbuster
|
||||
#define RADAR_CONTACT_STRIDER_MATERIAL "vgui/icons/icon_strider" // Strider
|
||||
#define RADAR_CONTACT_DOG_MATERIAL "vgui/icons/icon_dog" // Dog
|
||||
#define RADAR_CONTACT_BASE_MATERIAL "vgui/icons/icon_base" // Ally base
|
||||
|
||||
static CHudRadar *s_Radar = NULL;
|
||||
|
||||
CHudRadar *GetHudRadar()
|
||||
{
|
||||
return s_Radar;
|
||||
}
|
||||
|
||||
DECLARE_HUDELEMENT( CMapOverview );
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
CHudRadar::CHudRadar( vgui::Panel *parent, const char *panelName ) : BaseClass( parent, panelName )
|
||||
{
|
||||
m_pVehicle = NULL;
|
||||
m_iImageID = -1;
|
||||
m_textureID_IconLambda = -1;
|
||||
m_textureID_IconBuster = -1;
|
||||
m_textureID_IconStrider = -1;
|
||||
m_textureID_IconDog = -1;
|
||||
m_textureID_IconBase = -1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
CHudRadar::~CHudRadar()
|
||||
{
|
||||
s_Radar = NULL;
|
||||
|
||||
#if defined(_X360)
|
||||
if( m_iImageID != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_iImageID );
|
||||
m_iImageID = -1;
|
||||
}
|
||||
|
||||
if( m_textureID_IconLambda != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_textureID_IconLambda );
|
||||
m_textureID_IconLambda = -1;
|
||||
}
|
||||
|
||||
if( m_textureID_IconBuster != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_textureID_IconBuster );
|
||||
m_textureID_IconBuster = -1;
|
||||
}
|
||||
|
||||
if( m_textureID_IconStrider != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_textureID_IconStrider );
|
||||
m_textureID_IconStrider = -1;
|
||||
}
|
||||
|
||||
if( m_textureID_IconDog != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_textureID_IconDog );
|
||||
m_textureID_IconDog = -1;
|
||||
}
|
||||
|
||||
if( m_textureID_IconBase != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID( m_textureID_IconBase );
|
||||
m_textureID_IconBase = -1;
|
||||
}
|
||||
#endif//_X360
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
bool CHudRadar::Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData )
|
||||
{
|
||||
bool result = BaseClass::Init( pKeyValues, pInitData );
|
||||
ClearAllRadarContacts();
|
||||
s_Radar = this;
|
||||
|
||||
m_ghostAlpha = 0;
|
||||
m_flTimeStartGhosting = gpGlobals->curtime + 1.0f;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
void CHudRadar::VidInit(void)
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
void CHudRadar::MsgFunc_UpdateRadar(bf_read &msg )
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Purpose: Register a radar contact in the list of contacts
|
||||
//---------------------------------------------------------
|
||||
void CHudRadar::AddRadarContact( const Vector &vecOrigin, int iType, float flTimeToLive )
|
||||
{
|
||||
if( m_iNumRadarContacts == RADAR_MAX_CONTACTS )
|
||||
return;
|
||||
|
||||
Vector v = vecOrigin;
|
||||
int iExistingContact = FindRadarContact( vecOrigin );
|
||||
|
||||
if( iExistingContact > -1 )
|
||||
{
|
||||
// Just update this contact.
|
||||
m_radarContacts[iExistingContact].m_flTimeToRemove = gpGlobals->curtime + flTimeToLive;
|
||||
return;
|
||||
}
|
||||
|
||||
m_radarContacts[m_iNumRadarContacts].m_vecOrigin = vecOrigin;
|
||||
m_radarContacts[m_iNumRadarContacts].m_iType = iType;
|
||||
m_radarContacts[m_iNumRadarContacts].m_flTimeToRemove = gpGlobals->curtime + flTimeToLive;
|
||||
m_iNumRadarContacts++;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Purpose: Search the contact list for a specific contact
|
||||
//---------------------------------------------------------
|
||||
int CHudRadar::FindRadarContact( const Vector &vecOrigin )
|
||||
{
|
||||
for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
|
||||
{
|
||||
if( m_radarContacts[ i ].m_vecOrigin == vecOrigin )
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Purpose: Go through all radar targets and see if any
|
||||
// have expired. If yes, remove them from the
|
||||
// list.
|
||||
//---------------------------------------------------------
|
||||
void CHudRadar::MaintainRadarContacts()
|
||||
{
|
||||
bool bKeepWorking = true;
|
||||
while( bKeepWorking )
|
||||
{
|
||||
bKeepWorking = false;
|
||||
for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
|
||||
{
|
||||
CRadarContact *pContact = &m_radarContacts[ i ];
|
||||
if( gpGlobals->curtime >= pContact->m_flTimeToRemove )
|
||||
{
|
||||
// Time for this guy to go. Easiest thing is just to copy the last element
|
||||
// into this element's spot and then decrement the count of entities.
|
||||
bKeepWorking = true;
|
||||
|
||||
m_radarContacts[ i ] = m_radarContacts[ m_iNumRadarContacts - 1 ];
|
||||
m_iNumRadarContacts--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
void CHudRadar::SetVisible(bool state)
|
||||
{
|
||||
BaseClass::SetVisible(state);
|
||||
|
||||
if( g_pMapOverview && g_pMapOverview->GetMode() == CMapOverview::MAP_MODE_RADAR )
|
||||
{
|
||||
// We are the hud element still, but he is in charge of the new style now.
|
||||
g_pMapOverview->SetVisible( state );
|
||||
}
|
||||
}
|
||||
|
||||
#define RADAR_BLIP_FADE_TIME 1.0f
|
||||
#define RADAR_USE_ICONS 1
|
||||
//---------------------------------------------------------
|
||||
// Purpose: Draw the radar panel.
|
||||
// We're probably doing too much other work in here
|
||||
//---------------------------------------------------------
|
||||
void CHudRadar::Paint()
|
||||
{
|
||||
if (m_iImageID == -1 )
|
||||
{
|
||||
// Set up the image ID's if they've somehow gone bad.
|
||||
m_textureID_IconLambda = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_textureID_IconLambda, RADAR_CONTACT_LAMBDA_MATERIAL, true, false );
|
||||
|
||||
m_textureID_IconBuster = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_textureID_IconBuster, RADAR_CONTACT_BUSTER_MATERIAL, true, false );
|
||||
|
||||
m_textureID_IconStrider = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_textureID_IconStrider, RADAR_CONTACT_STRIDER_MATERIAL, true, false );
|
||||
|
||||
m_textureID_IconDog = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_textureID_IconDog, RADAR_CONTACT_DOG_MATERIAL, true, false );
|
||||
|
||||
m_textureID_IconBase = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_textureID_IconBase, RADAR_CONTACT_BASE_MATERIAL, true, false );
|
||||
|
||||
m_iImageID = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_iImageID, RADAR_PANEL_MATERIAL, true, false );
|
||||
}
|
||||
|
||||
// Draw the radar background.
|
||||
int wide, tall;
|
||||
GetSize(wide, tall);
|
||||
int alpha = 255;
|
||||
vgui::surface()->DrawSetColor(255, 255, 255, alpha);
|
||||
vgui::surface()->DrawSetTexture(m_iImageID);
|
||||
vgui::surface()->DrawTexturedRect(0, 0, wide, tall);
|
||||
|
||||
// Manage the CRT 'ghosting' effect
|
||||
if( gpGlobals->curtime > m_flTimeStartGhosting )
|
||||
{
|
||||
if( m_ghostAlpha < RADAR_MAX_GHOST_ALPHA )
|
||||
{
|
||||
m_ghostAlpha++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flTimeStartGhosting = FLT_MAX;
|
||||
m_flTimeStopGhosting = gpGlobals->curtime + RandomFloat( 1.0f, 2.0f );// How long to ghost for
|
||||
}
|
||||
}
|
||||
else if( gpGlobals->curtime > m_flTimeStopGhosting )
|
||||
{
|
||||
// We're supposed to stop ghosting now.
|
||||
if( m_ghostAlpha > 0 )
|
||||
{
|
||||
// Still fading the effects.
|
||||
m_ghostAlpha--;
|
||||
}
|
||||
else
|
||||
{
|
||||
// DONE fading the effects. Now stop ghosting for a short while
|
||||
m_flTimeStartGhosting = gpGlobals->curtime + RandomFloat( 2.0f, 3.0f );// how long between ghosts
|
||||
m_flTimeStopGhosting = FLT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
// Now go through the list of radar targets and represent them on the radar screen
|
||||
// by drawing their icons on top of the background.
|
||||
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
|
||||
for( int i = 0 ; i < m_iNumRadarContacts ; i++ )
|
||||
{
|
||||
int alpha = 90;
|
||||
CRadarContact *pContact = &m_radarContacts[ i ];
|
||||
float deltaT = pContact->m_flTimeToRemove - gpGlobals->curtime;
|
||||
if ( deltaT < RADAR_BLIP_FADE_TIME )
|
||||
{
|
||||
float factor = deltaT / RADAR_BLIP_FADE_TIME;
|
||||
|
||||
alpha = (int) ( ((float)alpha) * factor );
|
||||
|
||||
if( alpha < 10 )
|
||||
alpha = 10;
|
||||
}
|
||||
|
||||
if( RADAR_USE_ICONS )
|
||||
{
|
||||
int flicker = RandomInt( 0, 30 );
|
||||
DrawIconOnRadar( pContact->m_vecOrigin, pLocalPlayer, pContact->m_iType, RADAR_IGNORE_Z, 255, 255, 255, alpha + flicker );
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawPositionOnRadar( pContact->m_vecOrigin, pLocalPlayer, pContact->m_iType, RADAR_IGNORE_Z, 255, 255, 255, alpha );
|
||||
}
|
||||
}
|
||||
|
||||
MaintainRadarContacts();
|
||||
}
|
||||
|
||||
ConVar radar_range("radar_range", "3000" ); // 180 feet
|
||||
//---------------------------------------------------------
|
||||
// Scale maps the distance of the target from the radar
|
||||
// source.
|
||||
//
|
||||
// 1.0 = target at or beyond radar range.
|
||||
// 0.5 = target at (radar_range * 0.5) units distance
|
||||
// 0.25 = target at (radar_range * 0.25) units distance
|
||||
// -etc-
|
||||
//---------------------------------------------------------
|
||||
bool CHudRadar::WorldToRadar( const Vector location, const Vector origin, const QAngle angles, float &x, float &y, float &z_delta, float &scale )
|
||||
{
|
||||
bool bInRange = true;
|
||||
|
||||
float x_diff = location.x - origin.x;
|
||||
float y_diff = location.y - origin.y;
|
||||
|
||||
// Supply epsilon values to avoid divide-by-zero
|
||||
if(x_diff == 0)
|
||||
x_diff = 0.00001f;
|
||||
|
||||
if(y_diff == 0)
|
||||
y_diff = 0.00001f;
|
||||
|
||||
int iRadarRadius = GetWide(); //width of the panel
|
||||
float fRange = radar_range.GetFloat();
|
||||
|
||||
// This magic /2.15 makes the radar scale seem smaller than the VGUI panel so the icons clamp
|
||||
// to the outer ring in the radar graphic, not the very edge of the panel itself.
|
||||
float fScale = (iRadarRadius/2.15f) / fRange;
|
||||
|
||||
float flOffset = atan(y_diff/x_diff);
|
||||
flOffset *= 180;
|
||||
flOffset /= M_PI;
|
||||
|
||||
if ((x_diff < 0) && (y_diff >= 0))
|
||||
flOffset = 180 + flOffset;
|
||||
else if ((x_diff < 0) && (y_diff < 0))
|
||||
flOffset = 180 + flOffset;
|
||||
else if ((x_diff >= 0) && (y_diff < 0))
|
||||
flOffset = 360 + flOffset;
|
||||
|
||||
y_diff = -1*(sqrt((x_diff)*(x_diff) + (y_diff)*(y_diff)));
|
||||
x_diff = 0;
|
||||
|
||||
flOffset = angles.y - flOffset;
|
||||
|
||||
flOffset *= M_PI;
|
||||
flOffset /= 180; // now theta is in radians
|
||||
|
||||
// Transform relative to radar source
|
||||
float xnew_diff = x_diff * cos(flOffset) - y_diff * sin(flOffset);
|
||||
float ynew_diff = x_diff * sin(flOffset) + y_diff * cos(flOffset);
|
||||
|
||||
if ( (-1 * y_diff) > fRange )
|
||||
{
|
||||
float flScale;
|
||||
|
||||
flScale = ( -1 * y_diff) / fRange;
|
||||
|
||||
xnew_diff /= (flScale);
|
||||
ynew_diff /= (flScale);
|
||||
|
||||
bInRange = false;
|
||||
|
||||
scale = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// scale
|
||||
float flDist = sqrt( ((xnew_diff)*(xnew_diff) + (ynew_diff)*(ynew_diff)) );
|
||||
scale = flDist / fRange;
|
||||
}
|
||||
|
||||
|
||||
// Scale the dot's position to match radar scale
|
||||
xnew_diff *= fScale;
|
||||
ynew_diff *= fScale;
|
||||
|
||||
// Translate to screen coordinates
|
||||
x = (iRadarRadius/2) + (int)xnew_diff;
|
||||
y = (iRadarRadius/2) + (int)ynew_diff;
|
||||
z_delta = 0.0f;
|
||||
|
||||
return bInRange;
|
||||
}
|
||||
|
||||
void CHudRadar::DrawPositionOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a )
|
||||
{
|
||||
float x, y, z_delta;
|
||||
int iBaseDotSize = 3;
|
||||
|
||||
QAngle viewAngle = pLocalPlayer->EyeAngles();
|
||||
|
||||
if( m_pVehicle != NULL )
|
||||
{
|
||||
viewAngle = m_pVehicle->GetAbsAngles();
|
||||
viewAngle.y += 90.0f;
|
||||
}
|
||||
|
||||
float flScale;
|
||||
|
||||
WorldToRadar( vecPos, pLocalPlayer->GetAbsOrigin(), viewAngle, x, y, z_delta, flScale );
|
||||
|
||||
if( flags & RADAR_IGNORE_Z )
|
||||
z_delta = 0;
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case RADAR_CONTACT_GENERIC:
|
||||
r = 255; g = 170; b = 0;
|
||||
iBaseDotSize *= 2;
|
||||
break;
|
||||
case RADAR_CONTACT_MAGNUSSEN_RDU:
|
||||
r = 0; g = 200; b = 255;
|
||||
iBaseDotSize *= 2;
|
||||
break;
|
||||
case RADAR_CONTACT_ENEMY:
|
||||
r = 255; g = 0; b = 0;
|
||||
iBaseDotSize *= 2;
|
||||
break;
|
||||
case RADAR_CONTACT_LARGE_ENEMY:
|
||||
r = 255; g = 0; b = 0;
|
||||
iBaseDotSize *= 3;
|
||||
break;
|
||||
}
|
||||
|
||||
DrawRadarDot( x, y, z_delta, iBaseDotSize, flags, r, g, b, a );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Purpose: Compute the proper position on the radar screen
|
||||
// for this object's position relative to the player.
|
||||
// Then draw the icon in the proper location on the
|
||||
// radar screen.
|
||||
//---------------------------------------------------------
|
||||
#define RADAR_ICON_MIN_SCALE 0.75f
|
||||
#define RADAR_ICON_MAX_SCALE 1.0f
|
||||
void CHudRadar::DrawIconOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a )
|
||||
{
|
||||
float x, y, z_delta;
|
||||
int wide, tall;
|
||||
|
||||
// for 'ghosting' CRT effects:
|
||||
int xmod;
|
||||
int ymod;
|
||||
int xoffset;
|
||||
int yoffset;
|
||||
|
||||
// Assume we're going to use the player's location and orientation
|
||||
QAngle viewAngle = pLocalPlayer->EyeAngles();
|
||||
Vector viewOrigin = pLocalPlayer->GetAbsOrigin();
|
||||
|
||||
// However, happily use those of the vehicle if available!
|
||||
if( m_pVehicle != NULL )
|
||||
{
|
||||
viewAngle = m_pVehicle->GetAbsAngles();
|
||||
viewAngle.y += 90.0f;
|
||||
viewOrigin = m_pVehicle->WorldSpaceCenter();
|
||||
}
|
||||
|
||||
float flScale;
|
||||
|
||||
WorldToRadar( vecPos, viewOrigin, viewAngle, x, y, z_delta, flScale );
|
||||
|
||||
flScale = RemapVal( flScale, 1.0f, 0.0f, RADAR_ICON_MIN_SCALE, RADAR_ICON_MAX_SCALE );
|
||||
|
||||
// Get the correct icon for this type of contact
|
||||
int iTextureID_Icon = -1;
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case RADAR_CONTACT_GENERIC:
|
||||
iTextureID_Icon = m_textureID_IconLambda;
|
||||
break;
|
||||
case RADAR_CONTACT_MAGNUSSEN_RDU:
|
||||
iTextureID_Icon = m_textureID_IconBuster;
|
||||
break;
|
||||
case RADAR_CONTACT_LARGE_ENEMY:
|
||||
case RADAR_CONTACT_ENEMY:
|
||||
iTextureID_Icon = m_textureID_IconStrider;
|
||||
break;
|
||||
case RADAR_CONTACT_DOG:
|
||||
iTextureID_Icon = m_textureID_IconDog;
|
||||
break;
|
||||
case RADAR_CONTACT_ALLY_INSTALLATION:
|
||||
iTextureID_Icon = m_textureID_IconBase;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
vgui::surface()->DrawSetColor( r, g, b, a );
|
||||
vgui::surface()->DrawSetTexture( iTextureID_Icon );
|
||||
vgui::surface()->DrawGetTextureSize( iTextureID_Icon, wide, tall );
|
||||
|
||||
wide = ( int((float)wide * flScale) );
|
||||
tall = ( int((float)tall * flScale) );
|
||||
|
||||
if( type == RADAR_CONTACT_LARGE_ENEMY )
|
||||
{
|
||||
wide *= 2;
|
||||
tall *= 2;
|
||||
}
|
||||
|
||||
// Center the icon around its position.
|
||||
x -= (wide >> 1);
|
||||
y -= (tall >> 1);
|
||||
|
||||
vgui::surface()->DrawTexturedRect(x, y, x+wide, y+tall);
|
||||
|
||||
// Draw the crt 'ghost' if the icon is not pegged to the outer rim
|
||||
if( flScale > RADAR_ICON_MIN_SCALE && m_ghostAlpha > 0 )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( r, g, b, m_ghostAlpha );
|
||||
xmod = RandomInt( 1, 4 );
|
||||
ymod = RandomInt( 1, 4 );
|
||||
xoffset = RandomInt( -1, 1 );
|
||||
yoffset = RandomInt( -1, 1 );
|
||||
x -= (xmod - xoffset);
|
||||
y -= (ymod - yoffset);
|
||||
wide += (xmod + xoffset);
|
||||
tall += (ymod + yoffset);
|
||||
vgui::surface()->DrawTexturedRect(x, y, x+wide, y+tall);
|
||||
}
|
||||
}
|
||||
|
||||
void CHudRadar::FillRect( int x, int y, int w, int h )
|
||||
{
|
||||
int panel_x, panel_y, panel_w, panel_h;
|
||||
GetBounds( panel_x, panel_y, panel_w, panel_h );
|
||||
vgui::surface()->DrawFilledRect( x, y, x+w, y+h );
|
||||
}
|
||||
|
||||
void CHudRadar::DrawRadarDot( int x, int y, float z_diff, int iBaseDotSize, int flags, int r, int g, int b, int a )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( r, g, b, a );
|
||||
|
||||
if ( z_diff < -128 ) // below the player
|
||||
{
|
||||
z_diff *= -1;
|
||||
|
||||
if ( z_diff > 3096 )
|
||||
{
|
||||
z_diff = 3096;
|
||||
}
|
||||
|
||||
int iBar = (int)( z_diff / 400 ) + 2;
|
||||
|
||||
// Draw an upside-down T shape to symbolize the dot is below the player.
|
||||
|
||||
iBaseDotSize /= 2;
|
||||
|
||||
//horiz
|
||||
FillRect( x-(2*iBaseDotSize), y, 5*iBaseDotSize, iBaseDotSize );
|
||||
|
||||
//vert
|
||||
FillRect( x, y - iBar*iBaseDotSize, iBaseDotSize, iBar*iBaseDotSize );
|
||||
}
|
||||
else if ( z_diff > 128 ) // above the player
|
||||
{
|
||||
if ( z_diff > 3096 )
|
||||
{
|
||||
z_diff = 3096;
|
||||
}
|
||||
|
||||
int iBar = (int)( z_diff / 400 ) + 2;
|
||||
|
||||
iBaseDotSize /= 2;
|
||||
|
||||
// Draw a T shape to symbolize the dot is above the player.
|
||||
|
||||
//horiz
|
||||
FillRect( x-(2*iBaseDotSize), y, 5*iBaseDotSize, iBaseDotSize );
|
||||
|
||||
//vert
|
||||
FillRect( x, y, iBaseDotSize, iBar*iBaseDotSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
FillRect( x, y, iBaseDotSize, iBaseDotSize );
|
||||
}
|
||||
}
|
||||
78
game/client/hl2/hud_radar.h
Normal file
78
game/client/hl2/hud_radar.h
Normal file
@@ -0,0 +1,78 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef HUD_RADAR_H
|
||||
#define HUD_RADAR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <vgui_controls/Panel.h>
|
||||
#include <vgui_controls/Label.h>
|
||||
#include "hl2_vehicle_radar.h"
|
||||
#include "c_vguiscreen.h"
|
||||
|
||||
class CRadarContact
|
||||
{
|
||||
public:
|
||||
Vector m_vecOrigin;
|
||||
int m_iType;
|
||||
float m_flTimeToRemove;
|
||||
};
|
||||
|
||||
class CHudRadar : public CVGuiScreenPanel
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS_SIMPLE( CHudRadar, CVGuiScreenPanel );
|
||||
|
||||
|
||||
CHudRadar( vgui::Panel *parent, const char *panelName );
|
||||
~CHudRadar();
|
||||
|
||||
virtual void Paint();
|
||||
void VidInit(void);
|
||||
virtual bool Init( KeyValues* pKeyValues, VGuiScreenInitData_t* pInitData );
|
||||
virtual void SetVisible(bool state);
|
||||
|
||||
void MsgFunc_UpdateRadar(bf_read &msg );
|
||||
void SetVehicle( C_BaseEntity *pVehicle ) { m_pVehicle = pVehicle; }
|
||||
|
||||
void AddRadarContact( const Vector &vecOrigin, int iType, float flTimeToLive );
|
||||
int FindRadarContact( const Vector &vecOrigin );
|
||||
void MaintainRadarContacts();
|
||||
|
||||
|
||||
void ClearAllRadarContacts() { m_iNumRadarContacts = 0; }
|
||||
|
||||
public:
|
||||
bool m_bUseFastUpdate;
|
||||
int m_ghostAlpha; // How intense the alpha channel is for CRT ghosts
|
||||
float m_flTimeStopGhosting;
|
||||
float m_flTimeStartGhosting;
|
||||
|
||||
private:
|
||||
|
||||
bool WorldToRadar( const Vector location, const Vector origin, const QAngle angles, float &x, float &y, float &z_delta, float &scale );
|
||||
|
||||
void DrawPositionOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a );
|
||||
void DrawIconOnRadar( Vector vecPos, C_BasePlayer *pLocalPlayer, int type, int flags, int r, int g, int b, int a );
|
||||
|
||||
void FillRect( int x, int y, int w, int h );
|
||||
void DrawRadarDot( int x, int y, float z_diff, int iBaseDotSize, int flags, int r, int g, int b, int a );
|
||||
|
||||
CRadarContact m_radarContacts[RADAR_MAX_CONTACTS];
|
||||
int m_iNumRadarContacts;
|
||||
C_BaseEntity *m_pVehicle;
|
||||
int m_iImageID;
|
||||
int m_textureID_IconLambda;
|
||||
int m_textureID_IconBuster;
|
||||
int m_textureID_IconStrider;
|
||||
int m_textureID_IconDog;
|
||||
int m_textureID_IconBase;
|
||||
};
|
||||
|
||||
extern CHudRadar *GetHudRadar();
|
||||
#endif // HUD_RADAR_H
|
||||
257
game/client/hl2/hud_suitpower.cpp
Normal file
257
game/client/hl2/hud_suitpower.cpp
Normal file
@@ -0,0 +1,257 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hud_suitpower.h"
|
||||
#include "hud_macros.h"
|
||||
#include "c_basehlplayer.h"
|
||||
#include "iclientmode.h"
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <vgui/ILocalize.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
DECLARE_HUDELEMENT( CHudSuitPower );
|
||||
|
||||
#define SUITPOWER_INIT -1
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudSuitPower::CHudSuitPower( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudSuitPower" )
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudSuitPower::Init( void )
|
||||
{
|
||||
m_flSuitPower = SUITPOWER_INIT;
|
||||
m_nSuitPowerLow = -1;
|
||||
m_iActiveSuitDevices = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudSuitPower::Reset( void )
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Save CPU cycles by letting the HUD system early cull
|
||||
// costly traversal. Called per frame, return true if thinking and
|
||||
// painting need to occur.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHudSuitPower::ShouldDraw()
|
||||
{
|
||||
bool bNeedsDraw = false;
|
||||
|
||||
C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pPlayer )
|
||||
return false;
|
||||
|
||||
// needs draw if suit power changed or animation in progress
|
||||
bNeedsDraw = ( ( pPlayer->m_HL2Local.m_flSuitPower != m_flSuitPower ) || ( m_AuxPowerColor[3] > 0 ) );
|
||||
|
||||
return ( bNeedsDraw && CHudElement::ShouldDraw() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudSuitPower::OnThink( void )
|
||||
{
|
||||
float flCurrentPower = 0;
|
||||
C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
flCurrentPower = pPlayer->m_HL2Local.m_flSuitPower;
|
||||
|
||||
// Only update if we've changed suit power
|
||||
if ( flCurrentPower == m_flSuitPower )
|
||||
return;
|
||||
|
||||
if ( flCurrentPower >= 100.0f && m_flSuitPower < 100.0f )
|
||||
{
|
||||
// we've reached max power
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerMax");
|
||||
}
|
||||
else if ( flCurrentPower < 100.0f && (m_flSuitPower >= 100.0f || m_flSuitPower == SUITPOWER_INIT) )
|
||||
{
|
||||
// we've lost power
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerNotMax");
|
||||
}
|
||||
|
||||
bool flashlightActive = pPlayer->IsFlashlightActive();
|
||||
bool sprintActive = pPlayer->IsSprinting();
|
||||
bool breatherActive = pPlayer->IsBreatherActive();
|
||||
int activeDevices = (int)flashlightActive + (int)sprintActive + (int)breatherActive;
|
||||
|
||||
if (activeDevices != m_iActiveSuitDevices)
|
||||
{
|
||||
m_iActiveSuitDevices = activeDevices;
|
||||
|
||||
switch ( m_iActiveSuitDevices )
|
||||
{
|
||||
default:
|
||||
case 3:
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerThreeItemsActive");
|
||||
break;
|
||||
case 2:
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerTwoItemsActive");
|
||||
break;
|
||||
case 1:
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerOneItemActive");
|
||||
break;
|
||||
case 0:
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerNoItemsActive");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_flSuitPower = flCurrentPower;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: draws the power bar
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudSuitPower::Paint()
|
||||
{
|
||||
C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
|
||||
if ( !pPlayer )
|
||||
return;
|
||||
|
||||
// get bar chunks
|
||||
int chunkCount = m_flBarWidth / (m_flBarChunkWidth + m_flBarChunkGap);
|
||||
int enabledChunks = (int)((float)chunkCount * (m_flSuitPower * 1.0f/100.0f) + 0.5f );
|
||||
|
||||
// see if we've changed power state
|
||||
int lowPower = 0;
|
||||
if (enabledChunks <= (chunkCount / 4))
|
||||
{
|
||||
lowPower = 1;
|
||||
}
|
||||
if (m_nSuitPowerLow != lowPower)
|
||||
{
|
||||
if (m_iActiveSuitDevices || m_flSuitPower < 100.0f)
|
||||
{
|
||||
if (lowPower)
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerDecreasedBelow25");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("SuitAuxPowerIncreasedAbove25");
|
||||
}
|
||||
m_nSuitPowerLow = lowPower;
|
||||
}
|
||||
}
|
||||
|
||||
// draw the suit power bar
|
||||
surface()->DrawSetColor( m_AuxPowerColor );
|
||||
int xpos = m_flBarInsetX, ypos = m_flBarInsetY;
|
||||
for (int i = 0; i < enabledChunks; i++)
|
||||
{
|
||||
surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
|
||||
xpos += (m_flBarChunkWidth + m_flBarChunkGap);
|
||||
}
|
||||
// draw the exhausted portion of the bar.
|
||||
surface()->DrawSetColor( Color( m_AuxPowerColor[0], m_AuxPowerColor[1], m_AuxPowerColor[2], m_iAuxPowerDisabledAlpha ) );
|
||||
for (int i = enabledChunks; i < chunkCount; i++)
|
||||
{
|
||||
surface()->DrawFilledRect( xpos, ypos, xpos + m_flBarChunkWidth, ypos + m_flBarHeight );
|
||||
xpos += (m_flBarChunkWidth + m_flBarChunkGap);
|
||||
}
|
||||
|
||||
// draw our name
|
||||
surface()->DrawSetTextFont(m_hTextFont);
|
||||
surface()->DrawSetTextColor(m_AuxPowerColor);
|
||||
surface()->DrawSetTextPos(text_xpos, text_ypos);
|
||||
|
||||
wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AUX_POWER");
|
||||
|
||||
if (tempString)
|
||||
{
|
||||
surface()->DrawPrintText(tempString, wcslen(tempString));
|
||||
}
|
||||
else
|
||||
{
|
||||
surface()->DrawPrintText(L"AUX POWER", wcslen(L"AUX POWER"));
|
||||
}
|
||||
|
||||
if ( m_iActiveSuitDevices )
|
||||
{
|
||||
// draw the additional text
|
||||
int ypos = text2_ypos;
|
||||
|
||||
if (pPlayer->IsBreatherActive())
|
||||
{
|
||||
tempString = g_pVGuiLocalize->Find("#Valve_Hud_OXYGEN");
|
||||
|
||||
surface()->DrawSetTextPos(text2_xpos, ypos);
|
||||
|
||||
if (tempString)
|
||||
{
|
||||
surface()->DrawPrintText(tempString, wcslen(tempString));
|
||||
}
|
||||
else
|
||||
{
|
||||
surface()->DrawPrintText(L"OXYGEN", wcslen(L"OXYGEN"));
|
||||
}
|
||||
ypos += text2_gap;
|
||||
}
|
||||
|
||||
if (pPlayer->IsFlashlightActive())
|
||||
{
|
||||
tempString = g_pVGuiLocalize->Find("#Valve_Hud_FLASHLIGHT");
|
||||
|
||||
surface()->DrawSetTextPos(text2_xpos, ypos);
|
||||
|
||||
if (tempString)
|
||||
{
|
||||
surface()->DrawPrintText(tempString, wcslen(tempString));
|
||||
}
|
||||
else
|
||||
{
|
||||
surface()->DrawPrintText(L"FLASHLIGHT", wcslen(L"FLASHLIGHT"));
|
||||
}
|
||||
ypos += text2_gap;
|
||||
}
|
||||
|
||||
if (pPlayer->IsSprinting())
|
||||
{
|
||||
tempString = g_pVGuiLocalize->Find("#Valve_Hud_SPRINT");
|
||||
|
||||
surface()->DrawSetTextPos(text2_xpos, ypos);
|
||||
|
||||
if (tempString)
|
||||
{
|
||||
surface()->DrawPrintText(tempString, wcslen(tempString));
|
||||
}
|
||||
else
|
||||
{
|
||||
surface()->DrawPrintText(L"SPRINT", wcslen(L"SPRINT"));
|
||||
}
|
||||
ypos += text2_gap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
57
game/client/hl2/hud_suitpower.h
Normal file
57
game/client/hl2/hud_suitpower.h
Normal file
@@ -0,0 +1,57 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#if !defined( HUD_SUITPOWER_H )
|
||||
#define HUD_SUITPOWER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "hudelement.h"
|
||||
#include "hud_numericdisplay.h"
|
||||
#include <vgui_controls/Panel.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Shows the sprint power bar
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudSuitPower : public CHudElement, public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudSuitPower, vgui::Panel );
|
||||
|
||||
public:
|
||||
CHudSuitPower( const char *pElementName );
|
||||
virtual void Init( void );
|
||||
virtual void Reset( void );
|
||||
virtual void OnThink( void );
|
||||
bool ShouldDraw( void );
|
||||
|
||||
protected:
|
||||
virtual void Paint();
|
||||
|
||||
private:
|
||||
CPanelAnimationVar( Color, m_AuxPowerColor, "AuxPowerColor", "255 0 0 255" );
|
||||
CPanelAnimationVar( int, m_iAuxPowerDisabledAlpha, "AuxPowerDisabledAlpha", "70" );
|
||||
|
||||
CPanelAnimationVarAliasType( float, m_flBarInsetX, "BarInsetX", "8", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flBarInsetY, "BarInsetY", "8", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flBarWidth, "BarWidth", "80", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flBarHeight, "BarHeight", "10", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flBarChunkWidth, "BarChunkWidth", "10", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flBarChunkGap, "BarChunkGap", "2", "proportional_float" );
|
||||
|
||||
CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
|
||||
CPanelAnimationVarAliasType( float, text_xpos, "text_xpos", "8", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, text_ypos, "text_ypos", "20", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, text2_xpos, "text2_xpos", "8", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, text2_ypos, "text2_ypos", "40", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, text2_gap, "text2_gap", "10", "proportional_float" );
|
||||
|
||||
float m_flSuitPower;
|
||||
int m_nSuitPowerLow;
|
||||
int m_iActiveSuitDevices;
|
||||
};
|
||||
|
||||
#endif // HUD_SUITPOWER_H
|
||||
1525
game/client/hl2/hud_weaponselection.cpp
Normal file
1525
game/client/hl2/hud_weaponselection.cpp
Normal file
File diff suppressed because it is too large
Load Diff
272
game/client/hl2/hud_zoom.cpp
Normal file
272
game/client/hl2/hud_zoom.cpp
Normal file
@@ -0,0 +1,272 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hudelement.h"
|
||||
#include "hud_macros.h"
|
||||
#include "hud_numericdisplay.h"
|
||||
#include "iclientmode.h"
|
||||
#include "c_basehlplayer.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imesh.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "../hud_crosshair.h"
|
||||
|
||||
#include <vgui/IScheme.h>
|
||||
#include <vgui/ISurface.h>
|
||||
#include <KeyValues.h>
|
||||
#include <vgui_controls/AnimationController.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Draws the zoom screen
|
||||
//-----------------------------------------------------------------------------
|
||||
class CHudZoom : public vgui::Panel, public CHudElement
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( CHudZoom, vgui::Panel );
|
||||
|
||||
public:
|
||||
CHudZoom( const char *pElementName );
|
||||
|
||||
bool ShouldDraw( void );
|
||||
void Init( void );
|
||||
void LevelInit( void );
|
||||
|
||||
protected:
|
||||
virtual void ApplySchemeSettings(vgui::IScheme *scheme);
|
||||
virtual void Paint( void );
|
||||
|
||||
private:
|
||||
bool m_bZoomOn;
|
||||
float m_flZoomStartTime;
|
||||
bool m_bPainted;
|
||||
|
||||
CPanelAnimationVarAliasType( float, m_flCircle1Radius, "Circle1Radius", "66", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flCircle2Radius, "Circle2Radius", "74", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flDashGap, "DashGap", "16", "proportional_float" );
|
||||
CPanelAnimationVarAliasType( float, m_flDashHeight, "DashHeight", "4", "proportional_float" );
|
||||
|
||||
CMaterialReference m_ZoomMaterial;
|
||||
};
|
||||
|
||||
DECLARE_HUDELEMENT( CHudZoom );
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
//-----------------------------------------------------------------------------
|
||||
CHudZoom::CHudZoom( const char *pElementName ) : CHudElement(pElementName), BaseClass(NULL, "HudZoom")
|
||||
{
|
||||
vgui::Panel *pParent = g_pClientMode->GetViewport();
|
||||
SetParent( pParent );
|
||||
|
||||
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: standard hud element init function
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudZoom::Init( void )
|
||||
{
|
||||
m_bZoomOn = false;
|
||||
m_bPainted = false;
|
||||
m_flZoomStartTime = -999.0f;
|
||||
m_ZoomMaterial.Init( "vgui/zoom", TEXTURE_GROUP_VGUI );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: standard hud element init function
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudZoom::LevelInit( void )
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: sets scheme colors
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudZoom::ApplySchemeSettings( vgui::IScheme *scheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(scheme);
|
||||
|
||||
SetPaintBackgroundEnabled(false);
|
||||
SetPaintBorderEnabled(false);
|
||||
SetFgColor(scheme->GetColor("ZoomReticleColor", GetFgColor()));
|
||||
|
||||
SetForceStereoRenderToFrameBuffer( true );
|
||||
int x, y;
|
||||
int screenWide, screenTall;
|
||||
surface()->GetFullscreenViewport( x, y, screenWide, screenTall );
|
||||
SetBounds(0, 0, screenWide, screenTall);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Save CPU cycles by letting the HUD system early cull
|
||||
// costly traversal. Called per frame, return true if thinking and
|
||||
// painting need to occur.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CHudZoom::ShouldDraw( void )
|
||||
{
|
||||
bool bNeedsDraw = false;
|
||||
|
||||
C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer *>(C_BasePlayer::GetLocalPlayer());
|
||||
if ( pPlayer == NULL )
|
||||
return false;
|
||||
|
||||
if ( pPlayer->m_HL2Local.m_bZooming )
|
||||
{
|
||||
// need to paint
|
||||
bNeedsDraw = true;
|
||||
}
|
||||
else if ( m_bPainted )
|
||||
{
|
||||
// keep painting until state is finished
|
||||
bNeedsDraw = true;
|
||||
}
|
||||
|
||||
return ( bNeedsDraw && CHudElement::ShouldDraw() );
|
||||
}
|
||||
|
||||
#define ZOOM_FADE_TIME 0.4f
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: draws the zoom effect
|
||||
//-----------------------------------------------------------------------------
|
||||
void CHudZoom::Paint( void )
|
||||
{
|
||||
m_bPainted = false;
|
||||
|
||||
// see if we're zoomed any
|
||||
C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer *>(C_BasePlayer::GetLocalPlayer());
|
||||
if ( pPlayer == NULL )
|
||||
return;
|
||||
|
||||
if ( pPlayer->m_HL2Local.m_bZooming && m_bZoomOn == false )
|
||||
{
|
||||
m_bZoomOn = true;
|
||||
m_flZoomStartTime = gpGlobals->curtime;
|
||||
}
|
||||
else if ( pPlayer->m_HL2Local.m_bZooming == false && m_bZoomOn )
|
||||
{
|
||||
m_bZoomOn = false;
|
||||
m_flZoomStartTime = gpGlobals->curtime;
|
||||
}
|
||||
|
||||
// draw the appropriately scaled zoom animation
|
||||
float deltaTime = ( gpGlobals->curtime - m_flZoomStartTime );
|
||||
float scale = clamp( deltaTime / ZOOM_FADE_TIME, 0.0f, 1.0f );
|
||||
|
||||
float alpha;
|
||||
|
||||
if ( m_bZoomOn )
|
||||
{
|
||||
alpha = scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( scale >= 1.0f )
|
||||
return;
|
||||
|
||||
alpha = ( 1.0f - scale ) * 0.25f;
|
||||
scale = 1.0f - ( scale * 0.5f );
|
||||
}
|
||||
|
||||
Color col = GetFgColor();
|
||||
col[3] = alpha * 64;
|
||||
|
||||
surface()->DrawSetColor( col );
|
||||
|
||||
// draw zoom circles
|
||||
float fX, fY;
|
||||
bool bBehindCamera = false;
|
||||
CHudCrosshair::GetDrawPosition( &fX, &fY, &bBehindCamera );
|
||||
if( bBehindCamera )
|
||||
return;
|
||||
int xCrosshair = (int)fX;
|
||||
int yCrosshair = (int)fY;
|
||||
int wide, tall;
|
||||
GetSize( wide, tall );
|
||||
|
||||
surface()->DrawOutlinedCircle( xCrosshair, yCrosshair, m_flCircle1Radius * scale, 48);
|
||||
surface()->DrawOutlinedCircle( xCrosshair, yCrosshair, m_flCircle2Radius * scale, 64);
|
||||
|
||||
// draw dashed lines
|
||||
int dashCount = 2;
|
||||
int ypos = yCrosshair - m_flDashHeight / 2.f;
|
||||
float fGap = m_flDashGap * MAX(scale,0.1f);
|
||||
int dashMax = Max(fX, (float)wide - fX ) / fGap;
|
||||
while ( dashCount < dashMax )
|
||||
{
|
||||
int xpos = (int)(fX - fGap * dashCount + 0.5f);
|
||||
surface()->DrawFilledRect(xpos, ypos, xpos + 1, ypos + m_flDashHeight);
|
||||
xpos = (int)(fX + fGap * dashCount + 0.5f);
|
||||
surface()->DrawFilledRect(xpos, ypos, xpos + 1, ypos + m_flDashHeight);
|
||||
dashCount++;
|
||||
}
|
||||
|
||||
// draw the darkened edges, with a rotated texture in the four corners
|
||||
CMatRenderContextPtr pRenderContext( materials );
|
||||
pRenderContext->Bind( m_ZoomMaterial );
|
||||
IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, NULL );
|
||||
|
||||
float x0 = 0.0f, x1 = fX, x2 = wide;
|
||||
float y0 = 0.0f, y1 = fY, y2 = tall;
|
||||
|
||||
float uv1 = 1.0f - (1.0f / 255.0f);
|
||||
float uv2 = 0.0f + (1.0f / 255.0f);
|
||||
|
||||
struct coord_t
|
||||
{
|
||||
float x, y;
|
||||
float u, v;
|
||||
};
|
||||
coord_t coords[16] =
|
||||
{
|
||||
// top-left
|
||||
{ x0, y0, uv1, uv2 },
|
||||
{ x1, y0, uv2, uv2 },
|
||||
{ x1, y1, uv2, uv1 },
|
||||
{ x0, y1, uv1, uv1 },
|
||||
|
||||
// top-right
|
||||
{ x1, y0, uv2, uv2 },
|
||||
{ x2, y0, uv1, uv2 },
|
||||
{ x2, y1, uv1, uv1 },
|
||||
{ x1, y1, uv2, uv1 },
|
||||
|
||||
// bottom-right
|
||||
{ x1, y1, uv2, uv1 },
|
||||
{ x2, y1, uv1, uv1 },
|
||||
{ x2, y2, uv1, uv2 },
|
||||
{ x1, y2, uv2, uv2 },
|
||||
|
||||
// bottom-left
|
||||
{ x0, y1, uv1, uv1 },
|
||||
{ x1, y1, uv2, uv1 },
|
||||
{ x1, y2, uv2, uv2 },
|
||||
{ x0, y2, uv1, uv2 },
|
||||
};
|
||||
|
||||
CMeshBuilder meshBuilder;
|
||||
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 4 );
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
meshBuilder.Color4f( 0.0, 0.0, 0.0, alpha );
|
||||
meshBuilder.TexCoord2f( 0, coords[i].u, coords[i].v );
|
||||
meshBuilder.Position3f( coords[i].x, coords[i].y, 0.0f );
|
||||
meshBuilder.AdvanceVertex();
|
||||
}
|
||||
|
||||
meshBuilder.End();
|
||||
pMesh->Draw();
|
||||
|
||||
m_bPainted = true;
|
||||
}
|
||||
110
game/client/hl2/shieldproxy.cpp
Normal file
110
game/client/hl2/shieldproxy.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "proxyentity.h"
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "materialsystem/imaterialvar.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include <KeyValues.h>
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// $sineVar : name of variable that controls the alpha level (float)
|
||||
class CShieldProxy : public CEntityMaterialProxy
|
||||
{
|
||||
public:
|
||||
CShieldProxy();
|
||||
virtual ~CShieldProxy();
|
||||
virtual bool Init( IMaterial *pMaterial, KeyValues *pKeyValues );
|
||||
virtual void OnBind( C_BaseEntity *pC_BaseEntity );
|
||||
virtual IMaterial *GetMaterial();
|
||||
|
||||
private:
|
||||
IMaterialVar *m_AlphaVar;
|
||||
IMaterialVar *m_pTextureScrollVar;
|
||||
float m_ScrollRate;
|
||||
float m_ScrollAngle;
|
||||
};
|
||||
|
||||
CShieldProxy::CShieldProxy()
|
||||
{
|
||||
m_AlphaVar = NULL;
|
||||
m_pTextureScrollVar = NULL;
|
||||
m_ScrollRate = 0;
|
||||
m_ScrollAngle = 0;
|
||||
}
|
||||
|
||||
CShieldProxy::~CShieldProxy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool CShieldProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
|
||||
{
|
||||
bool foundVar;
|
||||
|
||||
m_AlphaVar = pMaterial->FindVar( "$translucency", &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
char const* pScrollVarName = pKeyValues->GetString( "textureScrollVar" );
|
||||
if (!pScrollVarName)
|
||||
return false;
|
||||
|
||||
m_pTextureScrollVar = pMaterial->FindVar( pScrollVarName, &foundVar, false );
|
||||
if( !foundVar )
|
||||
return false;
|
||||
|
||||
m_ScrollRate = pKeyValues->GetFloat( "textureScrollRate", 1 );
|
||||
m_ScrollAngle = pKeyValues->GetFloat( "textureScrollAngle", 0 );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CShieldProxy::OnBind( C_BaseEntity *pEnt )
|
||||
{
|
||||
if (m_AlphaVar)
|
||||
{
|
||||
m_AlphaVar->SetFloatValue( pEnt->m_clrRender->a );
|
||||
}
|
||||
|
||||
if( !m_pTextureScrollVar )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float sOffset, tOffset;
|
||||
|
||||
sOffset = gpGlobals->curtime * sin( m_ScrollAngle * ( M_PI / 180.0f ) ) * m_ScrollRate;
|
||||
tOffset = gpGlobals->curtime * cos( m_ScrollAngle * ( M_PI / 180.0f ) ) * m_ScrollRate;
|
||||
|
||||
// make sure that we are positive
|
||||
if( sOffset < 0.0f )
|
||||
{
|
||||
sOffset += 1.0f + -( int )sOffset;
|
||||
}
|
||||
if( tOffset < 0.0f )
|
||||
{
|
||||
tOffset += 1.0f + -( int )tOffset;
|
||||
}
|
||||
|
||||
// make sure that we are in a [0,1] range
|
||||
sOffset = sOffset - ( int )sOffset;
|
||||
tOffset = tOffset - ( int )tOffset;
|
||||
|
||||
m_pTextureScrollVar->SetVecValue( sOffset, tOffset, 0.0f );
|
||||
}
|
||||
|
||||
IMaterial *CShieldProxy::GetMaterial()
|
||||
{
|
||||
if ( !m_AlphaVar )
|
||||
return NULL;
|
||||
|
||||
return m_AlphaVar->GetOwningMaterial();
|
||||
}
|
||||
|
||||
EXPOSE_INTERFACE( CShieldProxy, IMaterialProxy, "Shield" IMATERIAL_PROXY_INTERFACE_VERSION );
|
||||
37
game/client/hl2/vgui_rootpanel_hl2.cpp
Normal file
37
game/client/hl2/vgui_rootpanel_hl2.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#include "cbase.h"
|
||||
#include "vgui_int.h"
|
||||
#include "ienginevgui.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VGUI_CreateClientDLLRootPanel( void )
|
||||
{
|
||||
// Just using PANEL_ROOT in HL2 right now
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void VGUI_DestroyClientDLLRootPanel( void )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Game specific root panel
|
||||
// Output : vgui::Panel
|
||||
//-----------------------------------------------------------------------------
|
||||
vgui::VPANEL VGui_GetClientDLLRootPanel( void )
|
||||
{
|
||||
vgui::VPANEL root = enginevgui->GetPanel( PANEL_CLIENTDLL );
|
||||
return root;
|
||||
}
|
||||
Reference in New Issue
Block a user