Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2236 lines
50 KiB

9 years ago
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
9 years ago
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "monsters.h"
#include "customentity.h"
#include "effects.h"
#include "weapons.h"
#include "decals.h"
#include "func_break.h"
#include "shake.h"
9 years ago
#define SF_GIBSHOOTER_REPEATABLE 1 // allows a gibshooter to be refired
9 years ago
#define SF_FUNNEL_REVERSE 1 // funnel effect repels particles instead of attracting them.
// Lightning target, just alias landmark
LINK_ENTITY_TO_CLASS( info_target, CPointEntity )
9 years ago
class CBubbling : public CBaseEntity
{
public:
9 years ago
void Spawn( void );
void Precache( void );
void KeyValue( KeyValueData *pkvd );
void EXPORT FizzThink( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
virtual int ObjectCaps( void ) { return CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
static TYPEDESCRIPTION m_SaveData[];
int m_density;
int m_frequency;
int m_bubbleModel;
int m_state;
9 years ago
};
LINK_ENTITY_TO_CLASS( env_bubbles, CBubbling )
9 years ago
TYPEDESCRIPTION CBubbling::m_SaveData[] =
9 years ago
{
DEFINE_FIELD( CBubbling, m_density, FIELD_INTEGER ),
DEFINE_FIELD( CBubbling, m_frequency, FIELD_INTEGER ),
DEFINE_FIELD( CBubbling, m_state, FIELD_INTEGER ),
// Let spawn restore this!
//DEFINE_FIELD( CBubbling, m_bubbleModel, FIELD_INTEGER ),
9 years ago
};
IMPLEMENT_SAVERESTORE( CBubbling, CBaseEntity )
9 years ago
#define SF_BUBBLES_STARTOFF 0x0001
void CBubbling::Spawn( void )
{
9 years ago
Precache();
SET_MODEL( ENT( pev ), STRING( pev->model ) ); // Set size
9 years ago
pev->solid = SOLID_NOT; // Remove model & collisions
pev->renderamt = 0; // The engine won't draw this model if this is set to 0 and blending is on
pev->rendermode = kRenderTransTexture;
int speed = fabs( pev->speed );
9 years ago
// HACKHACK!!! - Speed in rendercolor
pev->rendercolor.x = speed >> 8;
pev->rendercolor.y = speed & 255;
9 years ago
pev->rendercolor.z = ( pev->speed < 0 ) ? 1 : 0;
9 years ago
9 years ago
if( !( pev->spawnflags & SF_BUBBLES_STARTOFF ) )
9 years ago
{
SetThink( &CBubbling::FizzThink );
pev->nextthink = gpGlobals->time + 2.0f;
9 years ago
m_state = 1;
}
else
m_state = 0;
}
void CBubbling::Precache( void )
{
9 years ago
m_bubbleModel = PRECACHE_MODEL( "sprites/bubble.spr" ); // Precache bubble sprite
9 years ago
}
void CBubbling::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
9 years ago
if( ShouldToggle( useType, m_state ) )
9 years ago
m_state = !m_state;
9 years ago
if( m_state )
9 years ago
{
SetThink( &CBubbling::FizzThink );
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
}
else
{
SetThink( NULL );
pev->nextthink = 0;
}
}
void CBubbling::KeyValue( KeyValueData *pkvd )
{
9 years ago
if( FStrEq( pkvd->szKeyName, "density" ) )
9 years ago
{
9 years ago
m_density = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "frequency" ) )
9 years ago
{
9 years ago
m_frequency = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "current" ) )
9 years ago
{
9 years ago
pev->speed = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
else
CBaseEntity::KeyValue( pkvd );
}
void CBubbling::FizzThink( void )
{
9 years ago
MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, VecBModelOrigin( pev ) );
9 years ago
WRITE_BYTE( TE_FIZZ );
WRITE_SHORT( (short)ENTINDEX( edict() ) );
WRITE_SHORT( (short)m_bubbleModel );
WRITE_BYTE( m_density );
MESSAGE_END();
9 years ago
if( m_frequency > 19 )
pev->nextthink = gpGlobals->time + 0.5f;
9 years ago
else
pev->nextthink = gpGlobals->time + 2.5f - ( 0.1f * m_frequency );
9 years ago
}
// --------------------------------------------------
//
// Beams
//
// --------------------------------------------------
LINK_ENTITY_TO_CLASS( beam, CBeam )
9 years ago
void CBeam::Spawn( void )
{
pev->solid = SOLID_NOT; // Remove model & collisions
9 years ago
Precache();
9 years ago
}
void CBeam::Precache( void )
{
9 years ago
if( pev->owner )
9 years ago
SetStartEntity( ENTINDEX( pev->owner ) );
9 years ago
if( pev->aiment )
9 years ago
SetEndEntity( ENTINDEX( pev->aiment ) );
}
9 years ago
void CBeam::SetStartEntity( int entityIndex )
9 years ago
{
9 years ago
pev->sequence = ( entityIndex & 0x0FFF ) | ( ( pev->sequence & 0xF000 ) << 12 );
9 years ago
pev->owner = g_engfuncs.pfnPEntityOfEntIndex( entityIndex );
}
9 years ago
void CBeam::SetEndEntity( int entityIndex )
9 years ago
{
9 years ago
pev->skin = ( entityIndex & 0x0FFF ) | ( ( pev->skin & 0xF000 ) << 12 );
9 years ago
pev->aiment = g_engfuncs.pfnPEntityOfEntIndex( entityIndex );
}
// These don't take attachments into account
const Vector &CBeam::GetStartPos( void )
{
9 years ago
if( GetType() == BEAM_ENTS )
9 years ago
{
edict_t *pent = g_engfuncs.pfnPEntityOfEntIndex( GetStartEntity() );
return pent->v.origin;
}
return pev->origin;
}
const Vector &CBeam::GetEndPos( void )
{
int type = GetType();
9 years ago
if( type == BEAM_POINTS || type == BEAM_HOSE )
9 years ago
{
return pev->angles;
}
edict_t *pent = g_engfuncs.pfnPEntityOfEntIndex( GetEndEntity() );
9 years ago
if( pent )
9 years ago
return pent->v.origin;
return pev->angles;
}
CBeam *CBeam::BeamCreate( const char *pSpriteName, int width )
{
// Create a new entity with CBeam private data
CBeam *pBeam = GetClassPtr( (CBeam *)NULL );
9 years ago
pBeam->pev->classname = MAKE_STRING( "beam" );
9 years ago
pBeam->BeamInit( pSpriteName, width );
return pBeam;
}
void CBeam::BeamInit( const char *pSpriteName, int width )
{
pev->flags |= FL_CUSTOMENTITY;
SetColor( 255, 255, 255 );
SetBrightness( 255 );
SetNoise( 0 );
SetFrame( 0 );
SetScrollRate( 0 );
pev->model = MAKE_STRING( pSpriteName );
SetTexture( PRECACHE_MODEL( pSpriteName ) );
9 years ago
SetWidth( width );
pev->skin = 0;
pev->sequence = 0;
pev->rendermode = 0;
}
void CBeam::PointsInit( const Vector &start, const Vector &end )
{
SetType( BEAM_POINTS );
SetStartPos( start );
SetEndPos( end );
SetStartAttachment( 0 );
SetEndAttachment( 0 );
RelinkBeam();
}
void CBeam::HoseInit( const Vector &start, const Vector &direction )
{
SetType( BEAM_HOSE );
SetStartPos( start );
SetEndPos( direction );
SetStartAttachment( 0 );
SetEndAttachment( 0 );
RelinkBeam();
}
void CBeam::PointEntInit( const Vector &start, int endIndex )
{
SetType( BEAM_ENTPOINT );
SetStartPos( start );
SetEndEntity( endIndex );
SetStartAttachment( 0 );
SetEndAttachment( 0 );
RelinkBeam();
}
void CBeam::EntsInit( int startIndex, int endIndex )
{
SetType( BEAM_ENTS );
SetStartEntity( startIndex );
SetEndEntity( endIndex );
SetStartAttachment( 0 );
SetEndAttachment( 0 );
RelinkBeam();
}
void CBeam::RelinkBeam( void )
{
const Vector &startPos = GetStartPos(), &endPos = GetEndPos();
pev->mins.x = Q_min( startPos.x, endPos.x );
pev->mins.y = Q_min( startPos.y, endPos.y );
pev->mins.z = Q_min( startPos.z, endPos.z );
pev->maxs.x = Q_max( startPos.x, endPos.x );
pev->maxs.y = Q_max( startPos.y, endPos.y );
pev->maxs.z = Q_max( startPos.z, endPos.z );
9 years ago
pev->mins = pev->mins - pev->origin;
pev->maxs = pev->maxs - pev->origin;
UTIL_SetSize( pev, pev->mins, pev->maxs );
UTIL_SetOrigin( pev, pev->origin );
}
#if 0
void CBeam::SetObjectCollisionBox( void )
{
const Vector &startPos = GetStartPos(), &endPos = GetEndPos();
pev->absmin.x = min( startPos.x, endPos.x );
pev->absmin.y = min( startPos.y, endPos.y );
pev->absmin.z = min( startPos.z, endPos.z );
pev->absmax.x = max( startPos.x, endPos.x );
pev->absmax.y = max( startPos.y, endPos.y );
pev->absmax.z = max( startPos.z, endPos.z );
}
#endif
void CBeam::TriggerTouch( CBaseEntity *pOther )
{
9 years ago
if( pOther->pev->flags & ( FL_CLIENT | FL_MONSTER ) )
9 years ago
{
9 years ago
if( pev->owner )
9 years ago
{
9 years ago
CBaseEntity *pOwner = CBaseEntity::Instance( pev->owner );
9 years ago
pOwner->Use( pOther, this, USE_TOGGLE, 0 );
}
ALERT( at_console, "Firing targets!!!\n" );
}
}
CBaseEntity *CBeam::RandomTargetname( const char *szName )
{
int total = 0;
CBaseEntity *pEntity = NULL;
CBaseEntity *pNewEntity = NULL;
9 years ago
while( ( pNewEntity = UTIL_FindEntityByTargetname( pNewEntity, szName ) ) != NULL )
9 years ago
{
total++;
9 years ago
if( RANDOM_LONG( 0, total - 1 ) < 1 )
9 years ago
pEntity = pNewEntity;
}
return pEntity;
}
void CBeam::DoSparks( const Vector &start, const Vector &end )
{
9 years ago
if( pev->spawnflags & ( SF_BEAM_SPARKSTART | SF_BEAM_SPARKEND ) )
9 years ago
{
9 years ago
if( pev->spawnflags & SF_BEAM_SPARKSTART )
9 years ago
{
UTIL_Sparks( start );
}
9 years ago
if( pev->spawnflags & SF_BEAM_SPARKEND )
9 years ago
{
UTIL_Sparks( end );
}
}
}
class CLightning : public CBeam
{
public:
9 years ago
void Spawn( void );
void Precache( void );
void KeyValue( KeyValueData *pkvd );
void Activate( void );
void EXPORT StrikeThink( void );
void EXPORT DamageThink( void );
void RandomArea( void );
void RandomPoint( Vector &vecSrc );
void Zap( const Vector &vecSrc, const Vector &vecDest );
void EXPORT StrikeUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void EXPORT ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
9 years ago
inline BOOL ServerSide( void )
{
9 years ago
if( m_life == 0 && !( pev->spawnflags & SF_BEAM_RING ) )
9 years ago
return TRUE;
return FALSE;
}
9 years ago
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
9 years ago
9 years ago
void BeamUpdateVars( void );
9 years ago
int m_active;
string_t m_iszStartEntity;
string_t m_iszEndEntity;
9 years ago
float m_life;
9 years ago
int m_boltWidth;
int m_noiseAmplitude;
int m_brightness;
int m_speed;
9 years ago
float m_restrike;
9 years ago
int m_spriteTexture;
string_t m_iszSpriteName;
9 years ago
int m_frameStart;
9 years ago
float m_radius;
};
LINK_ENTITY_TO_CLASS( env_lightning, CLightning )
LINK_ENTITY_TO_CLASS( env_beam, CLightning )
9 years ago
// UNDONE: Jay -- This is only a test
#if _DEBUG
class CTripBeam : public CLightning
{
void Spawn( void );
};
LINK_ENTITY_TO_CLASS( trip_beam, CTripBeam )
9 years ago
void CTripBeam::Spawn( void )
{
CLightning::Spawn();
SetTouch( &CLightning::TriggerTouch );
9 years ago
pev->solid = SOLID_TRIGGER;
RelinkBeam();
}
#endif
9 years ago
TYPEDESCRIPTION CLightning::m_SaveData[] =
9 years ago
{
DEFINE_FIELD( CLightning, m_active, FIELD_INTEGER ),
DEFINE_FIELD( CLightning, m_iszStartEntity, FIELD_STRING ),
DEFINE_FIELD( CLightning, m_iszEndEntity, FIELD_STRING ),
DEFINE_FIELD( CLightning, m_life, FIELD_FLOAT ),
DEFINE_FIELD( CLightning, m_boltWidth, FIELD_INTEGER ),
DEFINE_FIELD( CLightning, m_noiseAmplitude, FIELD_INTEGER ),
DEFINE_FIELD( CLightning, m_brightness, FIELD_INTEGER ),
DEFINE_FIELD( CLightning, m_speed, FIELD_INTEGER ),
DEFINE_FIELD( CLightning, m_restrike, FIELD_FLOAT ),
DEFINE_FIELD( CLightning, m_spriteTexture, FIELD_INTEGER ),
DEFINE_FIELD( CLightning, m_iszSpriteName, FIELD_STRING ),
DEFINE_FIELD( CLightning, m_frameStart, FIELD_INTEGER ),
DEFINE_FIELD( CLightning, m_radius, FIELD_FLOAT ),
};
IMPLEMENT_SAVERESTORE( CLightning, CBeam )
9 years ago
void CLightning::Spawn( void )
{
9 years ago
if( FStringNull( m_iszSpriteName ) )
9 years ago
{
SetThink( &CBaseEntity::SUB_Remove );
return;
}
pev->solid = SOLID_NOT; // Remove model & collisions
9 years ago
Precache();
9 years ago
pev->dmgtime = gpGlobals->time;
9 years ago
if( ServerSide() )
9 years ago
{
SetThink( NULL );
9 years ago
if( pev->dmg > 0 )
9 years ago
{
SetThink( &CLightning::DamageThink );
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
}
9 years ago
if( pev->targetname )
9 years ago
{
9 years ago
if( !( pev->spawnflags & SF_BEAM_STARTON ) )
9 years ago
{
pev->effects = EF_NODRAW;
m_active = 0;
pev->nextthink = 0;
}
else
m_active = 1;
SetUse( &CLightning::ToggleUse );
}
}
else
{
m_active = 0;
9 years ago
if( !FStringNull( pev->targetname ) )
9 years ago
{
SetUse( &CLightning::StrikeUse );
}
9 years ago
if( FStringNull( pev->targetname ) || FBitSet( pev->spawnflags, SF_BEAM_STARTON ) )
9 years ago
{
SetThink( &CLightning::StrikeThink );
pev->nextthink = gpGlobals->time + 1.0f;
9 years ago
}
}
}
void CLightning::Precache( void )
{
m_spriteTexture = PRECACHE_MODEL( STRING( m_iszSpriteName ) );
9 years ago
CBeam::Precache();
}
void CLightning::Activate( void )
{
9 years ago
if( ServerSide() )
9 years ago
BeamUpdateVars();
}
void CLightning::KeyValue( KeyValueData *pkvd )
{
9 years ago
if( FStrEq( pkvd->szKeyName, "LightningStart" ) )
9 years ago
{
m_iszStartEntity = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "LightningEnd" ) )
9 years ago
{
m_iszEndEntity = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "life" ) )
9 years ago
{
9 years ago
m_life = atof( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "BoltWidth" ) )
9 years ago
{
9 years ago
m_boltWidth = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "NoiseAmplitude" ) )
9 years ago
{
9 years ago
m_noiseAmplitude = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "TextureScroll" ) )
9 years ago
{
9 years ago
m_speed = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "StrikeTime" ) )
9 years ago
{
9 years ago
m_restrike = atof( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "texture" ) )
9 years ago
{
9 years ago
m_iszSpriteName = ALLOC_STRING( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "framestart" ) )
9 years ago
{
9 years ago
m_frameStart = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "Radius" ) )
9 years ago
{
m_radius = atof( pkvd->szValue );
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "damage" ) )
9 years ago
{
9 years ago
pev->dmg = atof( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
else
CBeam::KeyValue( pkvd );
}
void CLightning::ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
9 years ago
if( !ShouldToggle( useType, m_active ) )
9 years ago
return;
9 years ago
if( m_active )
9 years ago
{
m_active = 0;
pev->effects |= EF_NODRAW;
pev->nextthink = 0;
}
else
{
m_active = 1;
pev->effects &= ~EF_NODRAW;
DoSparks( GetStartPos(), GetEndPos() );
9 years ago
if( pev->dmg > 0 )
9 years ago
{
pev->nextthink = gpGlobals->time;
pev->dmgtime = gpGlobals->time;
}
}
}
void CLightning::StrikeUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
9 years ago
if( !ShouldToggle( useType, m_active ) )
9 years ago
return;
9 years ago
if( m_active )
9 years ago
{
m_active = 0;
SetThink( NULL );
}
else
{
SetThink( &CLightning::StrikeThink );
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
}
9 years ago
if( !FBitSet( pev->spawnflags, SF_BEAM_TOGGLE ) )
9 years ago
SetUse( NULL );
}
int IsPointEntity( CBaseEntity *pEnt )
{
9 years ago
if( !pEnt->pev->modelindex )
9 years ago
return 1;
9 years ago
if( FClassnameIs( pEnt->pev, "info_target" ) || FClassnameIs( pEnt->pev, "info_landmark" ) || FClassnameIs( pEnt->pev, "path_corner" ) )
9 years ago
return 1;
return 0;
}
void CLightning::StrikeThink( void )
{
9 years ago
if( m_life != 0 )
9 years ago
{
9 years ago
if( pev->spawnflags & SF_BEAM_RANDOM )
pev->nextthink = gpGlobals->time + m_life + RANDOM_FLOAT( 0.0f, m_restrike );
9 years ago
else
pev->nextthink = gpGlobals->time + m_life + m_restrike;
}
m_active = 1;
9 years ago
if( FStringNull( m_iszEndEntity ) )
9 years ago
{
9 years ago
if( FStringNull( m_iszStartEntity ) )
9 years ago
{
9 years ago
RandomArea();
9 years ago
}
else
{
9 years ago
CBaseEntity *pStart = RandomTargetname( STRING( m_iszStartEntity ) );
if( pStart != NULL )
9 years ago
RandomPoint( pStart->pev->origin );
else
9 years ago
ALERT( at_console, "env_beam: unknown entity \"%s\"\n", STRING( m_iszStartEntity ) );
9 years ago
}
return;
}
9 years ago
CBaseEntity *pStart = RandomTargetname( STRING( m_iszStartEntity ) );
CBaseEntity *pEnd = RandomTargetname( STRING( m_iszEndEntity ) );
9 years ago
9 years ago
if( pStart != NULL && pEnd != NULL )
9 years ago
{
9 years ago
if( IsPointEntity( pStart ) || IsPointEntity( pEnd ) )
9 years ago
{
9 years ago
if( pev->spawnflags & SF_BEAM_RING )
9 years ago
{
// don't work
return;
}
}
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
9 years ago
if( IsPointEntity( pStart ) || IsPointEntity( pEnd ) )
9 years ago
{
9 years ago
if( !IsPointEntity( pEnd ) ) // One point entity must be in pEnd
9 years ago
{
CBaseEntity *pTemp;
pTemp = pStart;
pStart = pEnd;
pEnd = pTemp;
}
9 years ago
if( !IsPointEntity( pStart ) ) // One sided
9 years ago
{
WRITE_BYTE( TE_BEAMENTPOINT );
WRITE_SHORT( pStart->entindex() );
9 years ago
WRITE_COORD( pEnd->pev->origin.x );
WRITE_COORD( pEnd->pev->origin.y );
WRITE_COORD( pEnd->pev->origin.z );
9 years ago
}
else
{
9 years ago
WRITE_BYTE( TE_BEAMPOINTS );
WRITE_COORD( pStart->pev->origin.x );
WRITE_COORD( pStart->pev->origin.y );
WRITE_COORD( pStart->pev->origin.z );
WRITE_COORD( pEnd->pev->origin.x );
WRITE_COORD( pEnd->pev->origin.y );
WRITE_COORD( pEnd->pev->origin.z );
9 years ago
}
}
else
{
9 years ago
if( pev->spawnflags & SF_BEAM_RING )
9 years ago
WRITE_BYTE( TE_BEAMRING );
else
WRITE_BYTE( TE_BEAMENTS );
WRITE_SHORT( pStart->entindex() );
WRITE_SHORT( pEnd->entindex() );
}
WRITE_SHORT( m_spriteTexture );
WRITE_BYTE( m_frameStart ); // framestart
9 years ago
WRITE_BYTE( (int)pev->framerate ); // framerate
WRITE_BYTE( (int)( m_life * 10.0f ) ); // life
9 years ago
WRITE_BYTE( m_boltWidth ); // width
WRITE_BYTE( m_noiseAmplitude ); // noise
WRITE_BYTE( (int)pev->rendercolor.x ); // r, g, b
WRITE_BYTE( (int)pev->rendercolor.y ); // r, g, b
WRITE_BYTE( (int)pev->rendercolor.z ); // r, g, b
WRITE_BYTE( (int)pev->renderamt ); // brightness
9 years ago
WRITE_BYTE( m_speed ); // speed
MESSAGE_END();
DoSparks( pStart->pev->origin, pEnd->pev->origin );
9 years ago
if( pev->dmg > 0 )
9 years ago
{
TraceResult tr;
UTIL_TraceLine( pStart->pev->origin, pEnd->pev->origin, dont_ignore_monsters, NULL, &tr );
BeamDamageInstant( &tr, pev->dmg );
}
}
}
void CBeam::BeamDamage( TraceResult *ptr )
{
RelinkBeam();
if( ptr->flFraction != 1.0f && ptr->pHit != NULL )
9 years ago
{
9 years ago
CBaseEntity *pHit = CBaseEntity::Instance( ptr->pHit );
if( pHit )
9 years ago
{
ClearMultiDamage();
9 years ago
pHit->TraceAttack( pev, pev->dmg * ( gpGlobals->time - pev->dmgtime ), ( ptr->vecEndPos - pev->origin ).Normalize(), ptr, DMG_ENERGYBEAM );
9 years ago
ApplyMultiDamage( pev, pev );
9 years ago
if( pev->spawnflags & SF_BEAM_DECALS )
9 years ago
{
9 years ago
if( pHit->IsBSPModel() )
UTIL_DecalTrace( ptr, DECAL_BIGSHOT1 + RANDOM_LONG( 0, 4 ) );
9 years ago
}
}
}
pev->dmgtime = gpGlobals->time;
}
void CLightning::DamageThink( void )
{
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
TraceResult tr;
UTIL_TraceLine( GetStartPos(), GetEndPos(), dont_ignore_monsters, NULL, &tr );
BeamDamage( &tr );
}
void CLightning::Zap( const Vector &vecSrc, const Vector &vecDest )
{
#if 1
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
9 years ago
WRITE_BYTE( TE_BEAMPOINTS );
WRITE_COORD( vecSrc.x );
WRITE_COORD( vecSrc.y );
WRITE_COORD( vecSrc.z );
WRITE_COORD( vecDest.x );
WRITE_COORD( vecDest.y );
WRITE_COORD( vecDest.z );
9 years ago
WRITE_SHORT( m_spriteTexture );
WRITE_BYTE( m_frameStart ); // framestart
9 years ago
WRITE_BYTE( (int)pev->framerate ); // framerate
WRITE_BYTE( (int)( m_life * 10.0f ) ); // life
9 years ago
WRITE_BYTE( m_boltWidth ); // width
WRITE_BYTE( m_noiseAmplitude ); // noise
WRITE_BYTE( (int)pev->rendercolor.x ); // r, g, b
WRITE_BYTE( (int)pev->rendercolor.y ); // r, g, b
WRITE_BYTE( (int)pev->rendercolor.z ); // r, g, b
WRITE_BYTE( (int)pev->renderamt ); // brightness
9 years ago
WRITE_BYTE( m_speed ); // speed
MESSAGE_END();
#else
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
9 years ago
WRITE_BYTE( TE_LIGHTNING );
WRITE_COORD( vecSrc.x );
WRITE_COORD( vecSrc.y );
WRITE_COORD( vecSrc.z );
WRITE_COORD( vecDest.x );
WRITE_COORD( vecDest.y );
WRITE_COORD( vecDest.z );
WRITE_BYTE( 10 );
WRITE_BYTE( 50 );
WRITE_BYTE( 40 );
WRITE_SHORT( m_spriteTexture );
9 years ago
MESSAGE_END();
#endif
DoSparks( vecSrc, vecDest );
}
void CLightning::RandomArea( void )
{
9 years ago
int iLoops;
9 years ago
9 years ago
for( iLoops = 0; iLoops < 10; iLoops++ )
9 years ago
{
Vector vecSrc = pev->origin;
Vector vecDir1 = Vector( RANDOM_FLOAT( -1.0f, 1.0f ), RANDOM_FLOAT( -1.0f, 1.0f ),RANDOM_FLOAT( -1.0f, 1.0f ) );
9 years ago
vecDir1 = vecDir1.Normalize();
9 years ago
TraceResult tr1;
UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, ignore_monsters, ENT( pev ), &tr1 );
9 years ago
if( tr1.flFraction == 1.0f )
9 years ago
continue;
Vector vecDir2;
9 years ago
do
{
vecDir2 = Vector( RANDOM_FLOAT( -1.0f, 1.0f ), RANDOM_FLOAT( -1.0f, 1.0f ),RANDOM_FLOAT( -1.0f, 1.0f ) );
} while( DotProduct( vecDir1, vecDir2 ) > 0.0f );
9 years ago
vecDir2 = vecDir2.Normalize();
9 years ago
TraceResult tr2;
UTIL_TraceLine( vecSrc, vecSrc + vecDir2 * m_radius, ignore_monsters, ENT( pev ), &tr2 );
9 years ago
if( tr2.flFraction == 1.0f )
9 years ago
continue;
if( ( tr1.vecEndPos - tr2.vecEndPos ).Length() < m_radius * 0.1f )
9 years ago
continue;
9 years ago
UTIL_TraceLine( tr1.vecEndPos, tr2.vecEndPos, ignore_monsters, ENT( pev ), &tr2 );
9 years ago
if( tr2.flFraction != 1.0f )
9 years ago
continue;
Zap( tr1.vecEndPos, tr2.vecEndPos );
break;
}
}
void CLightning::RandomPoint( Vector &vecSrc )
{
9 years ago
int iLoops;
9 years ago
9 years ago
for( iLoops = 0; iLoops < 10; iLoops++ )
9 years ago
{
Vector vecDir1 = Vector( RANDOM_FLOAT( -1.0f, 1.0f ), RANDOM_FLOAT( -1.0f, 1.0f ), RANDOM_FLOAT( -1.0f, 1.0f ) );
9 years ago
vecDir1 = vecDir1.Normalize();
9 years ago
TraceResult tr1;
UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, ignore_monsters, ENT( pev ), &tr1 );
9 years ago
if( ( tr1.vecEndPos - vecSrc ).Length() < m_radius * 0.1f )
9 years ago
continue;
if( tr1.flFraction == 1.0f )
9 years ago
continue;
Zap( vecSrc, tr1.vecEndPos );
break;
}
}
void CLightning::BeamUpdateVars( void )
{
int beamType;
int pointStart, pointEnd;
9 years ago
edict_t *pStart = FIND_ENTITY_BY_TARGETNAME( NULL, STRING( m_iszStartEntity ) );
edict_t *pEnd = FIND_ENTITY_BY_TARGETNAME ( NULL, STRING( m_iszEndEntity ) );
pointStart = IsPointEntity( CBaseEntity::Instance( pStart ) );
pointEnd = IsPointEntity( CBaseEntity::Instance( pEnd ) );
9 years ago
pev->skin = 0;
pev->sequence = 0;
pev->rendermode = 0;
pev->flags |= FL_CUSTOMENTITY;
pev->model = m_iszSpriteName;
SetTexture( m_spriteTexture );
beamType = BEAM_ENTS;
9 years ago
if( pointStart || pointEnd )
9 years ago
{
9 years ago
if( !pointStart ) // One point entity must be in pStart
9 years ago
{
edict_t *pTemp;
// Swap start & end
pTemp = pStart;
pStart = pEnd;
pEnd = pTemp;
int swap = pointStart;
pointStart = pointEnd;
pointEnd = swap;
}
9 years ago
if( !pointEnd )
9 years ago
beamType = BEAM_ENTPOINT;
else
beamType = BEAM_POINTS;
}
SetType( beamType );
9 years ago
if( beamType == BEAM_POINTS || beamType == BEAM_ENTPOINT || beamType == BEAM_HOSE )
9 years ago
{
SetStartPos( pStart->v.origin );
9 years ago
if( beamType == BEAM_POINTS || beamType == BEAM_HOSE )
9 years ago
SetEndPos( pEnd->v.origin );
else
9 years ago
SetEndEntity( ENTINDEX( pEnd ) );
9 years ago
}
else
{
9 years ago
SetStartEntity( ENTINDEX( pStart ) );
SetEndEntity( ENTINDEX( pEnd ) );
9 years ago
}
RelinkBeam();
SetWidth( m_boltWidth );
SetNoise( m_noiseAmplitude );
SetFrame( m_frameStart );
SetScrollRate( m_speed );
9 years ago
if( pev->spawnflags & SF_BEAM_SHADEIN )
9 years ago
SetFlags( BEAM_FSHADEIN );
9 years ago
else if( pev->spawnflags & SF_BEAM_SHADEOUT )
9 years ago
SetFlags( BEAM_FSHADEOUT );
}
LINK_ENTITY_TO_CLASS( env_laser, CLaser )
9 years ago
9 years ago
TYPEDESCRIPTION CLaser::m_SaveData[] =
9 years ago
{
DEFINE_FIELD( CLaser, m_pSprite, FIELD_CLASSPTR ),
DEFINE_FIELD( CLaser, m_iszSpriteName, FIELD_STRING ),
DEFINE_FIELD( CLaser, m_firePosition, FIELD_POSITION_VECTOR ),
};
IMPLEMENT_SAVERESTORE( CLaser, CBeam )
9 years ago
void CLaser::Spawn( void )
{
9 years ago
if( FStringNull( pev->model ) )
9 years ago
{
SetThink( &CBaseEntity::SUB_Remove );
return;
}
pev->solid = SOLID_NOT; // Remove model & collisions
9 years ago
Precache();
9 years ago
SetThink( &CLaser::StrikeThink );
pev->flags |= FL_CUSTOMENTITY;
PointsInit( pev->origin, pev->origin );
9 years ago
if( !m_pSprite && m_iszSpriteName )
m_pSprite = CSprite::SpriteCreate( STRING( m_iszSpriteName ), pev->origin, TRUE );
9 years ago
else
m_pSprite = NULL;
9 years ago
if( m_pSprite )
m_pSprite->SetTransparency( kRenderGlow, (int)pev->rendercolor.x, (int)pev->rendercolor.y, (int)pev->rendercolor.z, (int)pev->renderamt, (int)pev->renderfx );
9 years ago
9 years ago
if( pev->targetname && !( pev->spawnflags & SF_BEAM_STARTON ) )
9 years ago
TurnOff();
else
TurnOn();
}
void CLaser::Precache( void )
{
pev->modelindex = PRECACHE_MODEL( STRING( pev->model ) );
9 years ago
if( m_iszSpriteName )
PRECACHE_MODEL( STRING( m_iszSpriteName ) );
9 years ago
}
void CLaser::KeyValue( KeyValueData *pkvd )
{
9 years ago
if( FStrEq( pkvd->szKeyName, "LaserTarget" ) )
9 years ago
{
pev->message = ALLOC_STRING( pkvd->szValue );
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "width" ) )
9 years ago
{
9 years ago
SetWidth( (int)atof( pkvd->szValue ) );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "NoiseAmplitude" ) )
9 years ago
{
9 years ago
SetNoise( atoi( pkvd->szValue ) );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "TextureScroll" ) )
9 years ago
{
9 years ago
SetScrollRate( atoi( pkvd->szValue ) );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "texture" ) )
9 years ago
{
9 years ago
pev->model = ALLOC_STRING( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "EndSprite" ) )
9 years ago
{
9 years ago
m_iszSpriteName = ALLOC_STRING( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "framestart" ) )
9 years ago
{
9 years ago
pev->frame = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "damage" ) )
9 years ago
{
9 years ago
pev->dmg = atof( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
else
CBeam::KeyValue( pkvd );
}
int CLaser::IsOn( void )
{
9 years ago
if( pev->effects & EF_NODRAW )
9 years ago
return 0;
return 1;
}
void CLaser::TurnOff( void )
{
pev->effects |= EF_NODRAW;
pev->nextthink = 0;
9 years ago
if( m_pSprite )
9 years ago
m_pSprite->TurnOff();
}
void CLaser::TurnOn( void )
{
pev->effects &= ~EF_NODRAW;
9 years ago
if( m_pSprite )
9 years ago
m_pSprite->TurnOn();
pev->dmgtime = gpGlobals->time;
pev->nextthink = gpGlobals->time;
}
void CLaser::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
int active = IsOn();
9 years ago
if( !ShouldToggle( useType, active ) )
9 years ago
return;
9 years ago
if( active )
9 years ago
{
TurnOff();
}
else
{
TurnOn();
}
}
void CLaser::FireAtPoint( TraceResult &tr )
{
SetEndPos( tr.vecEndPos );
9 years ago
if( m_pSprite )
9 years ago
UTIL_SetOrigin( m_pSprite->pev, tr.vecEndPos );
BeamDamage( &tr );
DoSparks( GetStartPos(), tr.vecEndPos );
}
void CLaser::StrikeThink( void )
{
9 years ago
CBaseEntity *pEnd = RandomTargetname( STRING( pev->message ) );
9 years ago
9 years ago
if( pEnd )
9 years ago
m_firePosition = pEnd->pev->origin;
TraceResult tr;
UTIL_TraceLine( pev->origin, m_firePosition, dont_ignore_monsters, NULL, &tr );
FireAtPoint( tr );
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
}
class CGlow : public CPointEntity
{
public:
void Spawn( void );
void Think( void );
void Animate( float frames );
9 years ago
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
9 years ago
9 years ago
float m_lastTime;
float m_maxFrame;
9 years ago
};
LINK_ENTITY_TO_CLASS( env_glow, CGlow )
9 years ago
9 years ago
TYPEDESCRIPTION CGlow::m_SaveData[] =
9 years ago
{
DEFINE_FIELD( CGlow, m_lastTime, FIELD_TIME ),
DEFINE_FIELD( CGlow, m_maxFrame, FIELD_FLOAT ),
};
IMPLEMENT_SAVERESTORE( CGlow, CPointEntity )
9 years ago
void CGlow::Spawn( void )
{
9 years ago
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
pev->effects = 0;
pev->frame = 0;
9 years ago
PRECACHE_MODEL( STRING( pev->model ) );
9 years ago
SET_MODEL( ENT( pev ), STRING( pev->model ) );
9 years ago
m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1;
if( m_maxFrame > 1.0f && pev->framerate != 0 )
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
m_lastTime = gpGlobals->time;
}
void CGlow::Think( void )
{
9 years ago
Animate( pev->framerate * ( gpGlobals->time - m_lastTime ) );
9 years ago
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
m_lastTime = gpGlobals->time;
9 years ago
}
void CGlow::Animate( float frames )
{
9 years ago
if( m_maxFrame > 0 )
9 years ago
pev->frame = fmod( pev->frame + frames, m_maxFrame );
}
LINK_ENTITY_TO_CLASS( env_sprite, CSprite )
9 years ago
9 years ago
TYPEDESCRIPTION CSprite::m_SaveData[] =
9 years ago
{
DEFINE_FIELD( CSprite, m_lastTime, FIELD_TIME ),
DEFINE_FIELD( CSprite, m_maxFrame, FIELD_FLOAT ),
};
IMPLEMENT_SAVERESTORE( CSprite, CPointEntity )
9 years ago
void CSprite::Spawn( void )
{
9 years ago
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
pev->effects = 0;
pev->frame = 0;
9 years ago
Precache();
9 years ago
SET_MODEL( ENT( pev ), STRING( pev->model ) );
9 years ago
m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1;
9 years ago
if( pev->targetname && !( pev->spawnflags & SF_SPRITE_STARTON ) )
9 years ago
TurnOff();
else
TurnOn();
9 years ago
9 years ago
// Worldcraft only sets y rotation, copy to Z
9 years ago
if( pev->angles.y != 0 && pev->angles.z == 0 )
9 years ago
{
pev->angles.z = pev->angles.y;
pev->angles.y = 0;
}
}
void CSprite::Precache( void )
{
PRECACHE_MODEL( STRING( pev->model ) );
9 years ago
// Reset attachment after save/restore
9 years ago
if( pev->aiment )
9 years ago
SetAttachment( pev->aiment, pev->body );
else
{
// Clear attachment
pev->skin = 0;
pev->body = 0;
}
}
void CSprite::SpriteInit( const char *pSpriteName, const Vector &origin )
{
9 years ago
pev->model = MAKE_STRING( pSpriteName );
9 years ago
pev->origin = origin;
Spawn();
}
CSprite *CSprite::SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate )
{
CSprite *pSprite = GetClassPtr( (CSprite *)NULL );
pSprite->SpriteInit( pSpriteName, origin );
9 years ago
pSprite->pev->classname = MAKE_STRING( "env_sprite" );
9 years ago
pSprite->pev->solid = SOLID_NOT;
pSprite->pev->movetype = MOVETYPE_NOCLIP;
9 years ago
if( animate )
9 years ago
pSprite->TurnOn();
return pSprite;
}
void CSprite::AnimateThink( void )
{
9 years ago
Animate( pev->framerate * ( gpGlobals->time - m_lastTime ) );
9 years ago
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
m_lastTime = gpGlobals->time;
9 years ago
}
void CSprite::AnimateUntilDead( void )
{
9 years ago
if( gpGlobals->time > pev->dmgtime )
UTIL_Remove( this );
9 years ago
else
{
AnimateThink();
pev->nextthink = gpGlobals->time;
}
}
void CSprite::Expand( float scaleSpeed, float fadeSpeed )
{
pev->speed = scaleSpeed;
pev->health = fadeSpeed;
SetThink( &CSprite::ExpandThink );
pev->nextthink = gpGlobals->time;
9 years ago
m_lastTime = gpGlobals->time;
9 years ago
}
void CSprite::ExpandThink( void )
{
float frametime = gpGlobals->time - m_lastTime;
pev->scale += pev->speed * frametime;
pev->renderamt -= pev->health * frametime;
9 years ago
if( pev->renderamt <= 0 )
9 years ago
{
pev->renderamt = 0;
UTIL_Remove( this );
}
else
{
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
m_lastTime = gpGlobals->time;
9 years ago
}
}
void CSprite::Animate( float frames )
{
pev->frame += frames;
9 years ago
if( pev->frame > m_maxFrame )
9 years ago
{
9 years ago
if( pev->spawnflags & SF_SPRITE_ONCE )
9 years ago
{
TurnOff();
}
else
{
9 years ago
if( m_maxFrame > 0 )
9 years ago
pev->frame = fmod( pev->frame, m_maxFrame );
}
}
}
void CSprite::TurnOff( void )
{
pev->effects = EF_NODRAW;
pev->nextthink = 0;
}
void CSprite::TurnOn( void )
{
pev->effects = 0;
if( ( pev->framerate && m_maxFrame > 1.0f ) || ( pev->spawnflags & SF_SPRITE_ONCE ) )
9 years ago
{
SetThink( &CSprite::AnimateThink );
9 years ago
pev->nextthink = gpGlobals->time;
m_lastTime = gpGlobals->time;
}
pev->frame = 0;
}
void CSprite::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
int on = pev->effects != EF_NODRAW;
9 years ago
if( ShouldToggle( useType, on ) )
9 years ago
{
9 years ago
if( on )
9 years ago
{
TurnOff();
}
else
{
TurnOn();
}
}
}
class CGibShooter : public CBaseDelay
{
public:
9 years ago
void Spawn( void );
void Precache( void );
void KeyValue( KeyValueData *pkvd );
9 years ago
void EXPORT ShootThink( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual CGib *CreateGib( void );
9 years ago
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
static TYPEDESCRIPTION m_SaveData[];
9 years ago
9 years ago
int m_iGibs;
9 years ago
int m_iGibCapacity;
int m_iGibMaterial;
int m_iGibModelIndex;
float m_flGibVelocity;
float m_flVariance;
float m_flGibLife;
};
TYPEDESCRIPTION CGibShooter::m_SaveData[] =
{
DEFINE_FIELD( CGibShooter, m_iGibs, FIELD_INTEGER ),
DEFINE_FIELD( CGibShooter, m_iGibCapacity, FIELD_INTEGER ),
DEFINE_FIELD( CGibShooter, m_iGibMaterial, FIELD_INTEGER ),
DEFINE_FIELD( CGibShooter, m_iGibModelIndex, FIELD_INTEGER ),
DEFINE_FIELD( CGibShooter, m_flGibVelocity, FIELD_FLOAT ),
DEFINE_FIELD( CGibShooter, m_flVariance, FIELD_FLOAT ),
DEFINE_FIELD( CGibShooter, m_flGibLife, FIELD_FLOAT ),
};
IMPLEMENT_SAVERESTORE( CGibShooter, CBaseDelay )
LINK_ENTITY_TO_CLASS( gibshooter, CGibShooter )
9 years ago
9 years ago
void CGibShooter::Precache( void )
9 years ago
{
9 years ago
if( g_Language == LANGUAGE_GERMAN )
9 years ago
{
9 years ago
m_iGibModelIndex = PRECACHE_MODEL( "models/germanygibs.mdl" );
9 years ago
}
else
{
9 years ago
m_iGibModelIndex = PRECACHE_MODEL( "models/hgibs.mdl" );
9 years ago
}
}
void CGibShooter::KeyValue( KeyValueData *pkvd )
{
9 years ago
if( FStrEq( pkvd->szKeyName, "m_iGibs" ) )
9 years ago
{
9 years ago
m_iGibs = m_iGibCapacity = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "m_flVelocity" ) )
9 years ago
{
9 years ago
m_flGibVelocity = atof( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "m_flVariance" ) )
9 years ago
{
9 years ago
m_flVariance = atof( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "m_flGibLife" ) )
9 years ago
{
9 years ago
m_flGibLife = atof( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
else
{
CBaseDelay::KeyValue( pkvd );
}
}
void CGibShooter::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
SetThink( &CGibShooter::ShootThink );
pev->nextthink = gpGlobals->time;
}
void CGibShooter::Spawn( void )
{
Precache();
pev->solid = SOLID_NOT;
pev->effects = EF_NODRAW;
9 years ago
if( m_flDelay == 0 )
9 years ago
{
m_flDelay = 0.1;
}
9 years ago
if( m_flGibLife == 0 )
9 years ago
{
m_flGibLife = 25;
}
9 years ago
SetMovedir( pev );
9 years ago
pev->body = MODEL_FRAMES( m_iGibModelIndex );
}
9 years ago
CGib *CGibShooter::CreateGib( void )
9 years ago
{
9 years ago
if( CVAR_GET_FLOAT( "violence_hgibs" ) == 0 )
9 years ago
return NULL;
CGib *pGib = GetClassPtr( (CGib *)NULL );
pGib->Spawn( "models/hgibs.mdl" );
pGib->m_bloodColor = BLOOD_COLOR_RED;
9 years ago
if( pev->body <= 1 )
9 years ago
{
9 years ago
ALERT( at_aiconsole, "GibShooter Body is <= 1!\n" );
9 years ago
}
9 years ago
pGib->pev->body = RANDOM_LONG( 1, pev->body - 1 );// avoid throwing random amounts of the 0th gib. (skull).
9 years ago
return pGib;
}
9 years ago
void CGibShooter::ShootThink( void )
9 years ago
{
pev->nextthink = gpGlobals->time + m_flDelay;
Vector vecShootDir;
vecShootDir = pev->movedir;
vecShootDir = vecShootDir + gpGlobals->v_right * RANDOM_FLOAT( -1.0f, 1.0f ) * m_flVariance;;
vecShootDir = vecShootDir + gpGlobals->v_forward * RANDOM_FLOAT( -1.0f, 1.0f ) * m_flVariance;;
vecShootDir = vecShootDir + gpGlobals->v_up * RANDOM_FLOAT( -1.0f, 1.0f ) * m_flVariance;;
9 years ago
vecShootDir = vecShootDir.Normalize();
CGib *pGib = CreateGib();
9 years ago
if( pGib )
9 years ago
{
pGib->pev->origin = pev->origin;
pGib->pev->velocity = vecShootDir * m_flGibVelocity;
9 years ago
pGib->pev->avelocity.x = RANDOM_FLOAT( 100.0f, 200.0f );
pGib->pev->avelocity.y = RANDOM_FLOAT( 100.0f, 300.0f );
9 years ago
float thinkTime = pGib->pev->nextthink - gpGlobals->time;
pGib->m_lifeTime = ( m_flGibLife * RANDOM_FLOAT( 0.95f, 1.05f ) ); // +/- 5%
9 years ago
if( pGib->m_lifeTime < thinkTime )
9 years ago
{
pGib->pev->nextthink = gpGlobals->time + pGib->m_lifeTime;
pGib->m_lifeTime = 0;
}
}
9 years ago
if( --m_iGibs <= 0 )
9 years ago
{
9 years ago
if( pev->spawnflags & SF_GIBSHOOTER_REPEATABLE )
9 years ago
{
m_iGibs = m_iGibCapacity;
SetThink( NULL );
pev->nextthink = gpGlobals->time;
}
else
{
SetThink( &CBaseEntity::SUB_Remove );
pev->nextthink = gpGlobals->time;
}
}
}
class CEnvShooter : public CGibShooter
{
9 years ago
void Precache( void );
void KeyValue( KeyValueData *pkvd );
9 years ago
9 years ago
CGib *CreateGib( void );
9 years ago
};
LINK_ENTITY_TO_CLASS( env_shooter, CEnvShooter )
9 years ago
9 years ago
void CEnvShooter::KeyValue( KeyValueData *pkvd )
9 years ago
{
9 years ago
if( FStrEq( pkvd->szKeyName, "shootmodel" ) )
9 years ago
{
9 years ago
pev->model = ALLOC_STRING( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if ( FStrEq( pkvd->szKeyName, "shootsounds" ) )
9 years ago
{
9 years ago
int iNoise = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
switch( iNoise )
{
case 0:
m_iGibMaterial = matGlass;
break;
case 1:
m_iGibMaterial = matWood;
break;
case 2:
m_iGibMaterial = matMetal;
break;
case 3:
m_iGibMaterial = matFlesh;
break;
case 4:
m_iGibMaterial = matRocks;
break;
default:
case -1:
m_iGibMaterial = matNone;
break;
}
}
else
{
CGibShooter::KeyValue( pkvd );
}
}
9 years ago
void CEnvShooter::Precache( void )
9 years ago
{
m_iGibModelIndex = PRECACHE_MODEL( STRING( pev->model ) );
9 years ago
CBreakable::MaterialSoundPrecache( (Materials)m_iGibMaterial );
}
9 years ago
CGib *CEnvShooter::CreateGib( void )
9 years ago
{
CGib *pGib = GetClassPtr( (CGib *)NULL );
9 years ago
pGib->Spawn( STRING( pev->model ) );
9 years ago
int bodyPart = 0;
9 years ago
if( pev->body > 1 )
bodyPart = RANDOM_LONG( 0, pev->body - 1 );
9 years ago
pGib->pev->body = bodyPart;
pGib->m_bloodColor = DONT_BLEED;
pGib->m_material = m_iGibMaterial;
pGib->pev->rendermode = pev->rendermode;
pGib->pev->renderamt = pev->renderamt;
pGib->pev->rendercolor = pev->rendercolor;
pGib->pev->renderfx = pev->renderfx;
pGib->pev->scale = pev->scale;
pGib->pev->skin = pev->skin;
return pGib;
}
class CTestEffect : public CBaseDelay
{
public:
9 years ago
void Spawn( void );
void Precache( void );
9 years ago
// void KeyValue( KeyValueData *pkvd );
void EXPORT TestThink( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
9 years ago
int m_iLoop;
int m_iBeam;
CBeam *m_pBeam[24];
float m_flBeamTime[24];
float m_flStartTime;
9 years ago
};
LINK_ENTITY_TO_CLASS( test_effect, CTestEffect )
9 years ago
void CTestEffect::Spawn( void )
{
9 years ago
Precache();
9 years ago
}
void CTestEffect::Precache( void )
{
PRECACHE_MODEL( "sprites/lgtning.spr" );
}
void CTestEffect::TestThink( void )
{
int i;
9 years ago
float t = gpGlobals->time - m_flStartTime;
9 years ago
9 years ago
if( m_iBeam < 24 )
9 years ago
{
CBeam *pbeam = CBeam::BeamCreate( "sprites/lgtning.spr", 100 );
9 years ago
TraceResult tr;
9 years ago
Vector vecSrc = pev->origin;
Vector vecDir = Vector( RANDOM_FLOAT( -1.0f, 1.0f ), RANDOM_FLOAT( -1.0f, 1.0f ),RANDOM_FLOAT( -1.0f, 1.0f ) );
9 years ago
vecDir = vecDir.Normalize();
9 years ago
UTIL_TraceLine( vecSrc, vecSrc + vecDir * 128, ignore_monsters, ENT( pev ), &tr );
9 years ago
pbeam->PointsInit( vecSrc, tr.vecEndPos );
// pbeam->SetColor( 80, 100, 255 );
pbeam->SetColor( 255, 180, 100 );
pbeam->SetWidth( 100 );
pbeam->SetScrollRate( 12 );
m_flBeamTime[m_iBeam] = gpGlobals->time;
m_pBeam[m_iBeam] = pbeam;
m_iBeam++;
#if 0
Vector vecMid = ( vecSrc + tr.vecEndPos ) * 0.5f;
9 years ago
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
9 years ago
WRITE_BYTE( TE_DLIGHT );
WRITE_COORD( vecMid.x ); // X
WRITE_COORD( vecMid.y ); // Y
WRITE_COORD( vecMid.z ); // Z
9 years ago
WRITE_BYTE( 20 ); // radius * 0.1
WRITE_BYTE( 255 ); // r
WRITE_BYTE( 180 ); // g
WRITE_BYTE( 100 ); // b
WRITE_BYTE( 20 ); // time * 10
WRITE_BYTE( 0 ); // decay * 0.1
MESSAGE_END( );
#endif
}
if( t < 3.0f )
9 years ago
{
9 years ago
for( i = 0; i < m_iBeam; i++ )
9 years ago
{
t = ( gpGlobals->time - m_flBeamTime[i] ) / ( 3.0f + m_flStartTime - m_flBeamTime[i] );
m_pBeam[i]->SetBrightness( (int)( 255.0f * t ) );
9 years ago
// m_pBeam[i]->SetScrollRate( 20 * t );
}
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
}
else
{
9 years ago
for( i = 0; i < m_iBeam; i++ )
9 years ago
{
UTIL_Remove( m_pBeam[i] );
}
m_flStartTime = gpGlobals->time;
m_iBeam = 0;
// pev->nextthink = gpGlobals->time;
SetThink( NULL );
}
}
void CTestEffect::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
SetThink( &CTestEffect::TestThink );
pev->nextthink = gpGlobals->time + 0.1f;
9 years ago
m_flStartTime = gpGlobals->time;
}
// Blood effects
class CBlood : public CPointEntity
{
public:
9 years ago
void Spawn( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void KeyValue( KeyValueData *pkvd );
9 years ago
9 years ago
inline int Color( void )
{
return pev->impulse;
}
9 years ago
9 years ago
inline float BloodAmount( void )
{
return pev->dmg;
}
9 years ago
9 years ago
inline void SetColor( int color )
{
pev->impulse = color;
}
inline void SetBloodAmount( float amount )
{
pev->dmg = amount;
}
Vector Direction( void );
Vector BloodPosition( CBaseEntity *pActivator );
9 years ago
private:
};
LINK_ENTITY_TO_CLASS( env_blood, CBlood )
9 years ago
#define SF_BLOOD_RANDOM 0x0001
#define SF_BLOOD_STREAM 0x0002
#define SF_BLOOD_PLAYER 0x0004
#define SF_BLOOD_DECAL 0x0008
void CBlood::Spawn( void )
{
9 years ago
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
pev->effects = 0;
pev->frame = 0;
9 years ago
SetMovedir( pev );
}
void CBlood::KeyValue( KeyValueData *pkvd )
{
9 years ago
if( FStrEq( pkvd->szKeyName, "color" ) )
9 years ago
{
9 years ago
int color = atoi( pkvd->szValue );
9 years ago
switch( color )
{
case 1:
SetColor( BLOOD_COLOR_YELLOW );
break;
default:
SetColor( BLOOD_COLOR_RED );
break;
}
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "amount" ) )
9 years ago
{
9 years ago
SetBloodAmount( atof( pkvd->szValue ) );
9 years ago
pkvd->fHandled = TRUE;
}
else
CPointEntity::KeyValue( pkvd );
}
Vector CBlood::Direction( void )
{
9 years ago
if( pev->spawnflags & SF_BLOOD_RANDOM )
9 years ago
return UTIL_RandomBloodVector();
9 years ago
9 years ago
return pev->movedir;
}
Vector CBlood::BloodPosition( CBaseEntity *pActivator )
{
9 years ago
if( pev->spawnflags & SF_BLOOD_PLAYER )
9 years ago
{
edict_t *pPlayer;
9 years ago
if( pActivator && pActivator->IsPlayer() )
9 years ago
{
pPlayer = pActivator->edict();
}
else
pPlayer = g_engfuncs.pfnPEntityOfEntIndex( 1 );
9 years ago
if( pPlayer )
return( pPlayer->v.origin + pPlayer->v.view_ofs ) + Vector( RANDOM_FLOAT( -10.0f, 10.0f ), RANDOM_FLOAT( -10.0f, 10.0f ), RANDOM_FLOAT( -10.0f, 10.0f ) );
9 years ago
}
return pev->origin;
}
void CBlood::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
9 years ago
if( pev->spawnflags & SF_BLOOD_STREAM )
UTIL_BloodStream( BloodPosition( pActivator ), Direction(), ( Color() == BLOOD_COLOR_RED ) ? 70 : Color(), (int)BloodAmount() );
9 years ago
else
UTIL_BloodDrips( BloodPosition( pActivator ), Direction(), Color(), (int)BloodAmount() );
9 years ago
9 years ago
if( pev->spawnflags & SF_BLOOD_DECAL )
9 years ago
{
Vector forward = Direction();
Vector start = BloodPosition( pActivator );
TraceResult tr;
UTIL_TraceLine( start, start + forward * BloodAmount() * 2, ignore_monsters, NULL, &tr );
if( tr.flFraction != 1.0f )
9 years ago
UTIL_BloodDecalTrace( &tr, Color() );
}
}
// Screen shake
class CShake : public CPointEntity
{
public:
9 years ago
void Spawn( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void KeyValue( KeyValueData *pkvd );
inline float Amplitude( void )
{
return pev->scale;
}
inline float Frequency( void )
{
return pev->dmg_save;
}
inline float Duration( void )
{
return pev->dmg_take;
}
inline float Radius( void )
{
return pev->dmg;
}
inline void SetAmplitude( float amplitude )
{
pev->scale = amplitude;
}
inline void SetFrequency( float frequency )
{
pev->dmg_save = frequency;
}
inline void SetDuration( float duration )
{
pev->dmg_take = duration;
}
inline void SetRadius( float radius )
{
pev->dmg = radius;
}
9 years ago
private:
};
LINK_ENTITY_TO_CLASS( env_shake, CShake )
9 years ago
// pev->scale is amplitude
// pev->dmg_save is frequency
// pev->dmg_take is duration
// pev->dmg is radius
// radius of 0 means all players
// NOTE: UTIL_ScreenShake() will only shake players who are on the ground
#define SF_SHAKE_EVERYONE 0x0001 // Don't check radius
// UNDONE: These don't work yet
#define SF_SHAKE_DISRUPT 0x0002 // Disrupt controls
#define SF_SHAKE_INAIR 0x0004 // Shake players in air
void CShake::Spawn( void )
{
9 years ago
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
pev->effects = 0;
pev->frame = 0;
if( pev->spawnflags & SF_SHAKE_EVERYONE )
9 years ago
pev->dmg = 0;
}
void CShake::KeyValue( KeyValueData *pkvd )
{
9 years ago
if( FStrEq( pkvd->szKeyName, "amplitude" ) )
9 years ago
{
9 years ago
SetAmplitude( atof( pkvd->szValue ) );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "frequency" ) )
9 years ago
{
9 years ago
SetFrequency( atof( pkvd->szValue ) );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "duration" ) )
9 years ago
{
9 years ago
SetDuration( atof( pkvd->szValue ) );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "radius" ) )
9 years ago
{
9 years ago
SetRadius( atof( pkvd->szValue ) );
9 years ago
pkvd->fHandled = TRUE;
}
else
CPointEntity::KeyValue( pkvd );
}
void CShake::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
UTIL_ScreenShake( pev->origin, Amplitude(), Frequency(), Duration(), Radius() );
}
class CFade : public CPointEntity
{
public:
9 years ago
void Spawn( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void KeyValue( KeyValueData *pkvd );
inline float Duration( void )
{
return pev->dmg_take;
}
9 years ago
9 years ago
inline float HoldTime( void )
{
return pev->dmg_save;
}
inline void SetDuration( float duration )
{
pev->dmg_take = duration;
}
9 years ago
9 years ago
inline void SetHoldTime( float hold )
{
pev->dmg_save = hold;
}
9 years ago
private:
};
LINK_ENTITY_TO_CLASS( env_fade, CFade )
9 years ago
// pev->dmg_take is duration
// pev->dmg_save is hold duration
9 years ago
#define SF_FADE_IN 0x0001 // Fade in, not out
9 years ago
#define SF_FADE_MODULATE 0x0002 // Modulate, don't blend
#define SF_FADE_ONLYONE 0x0004
void CFade::Spawn( void )
{
9 years ago
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
pev->effects = 0;
pev->frame = 0;
9 years ago
}
void CFade::KeyValue( KeyValueData *pkvd )
{
9 years ago
if( FStrEq( pkvd->szKeyName, "duration" ) )
9 years ago
{
9 years ago
SetDuration( atof( pkvd->szValue ) );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "holdtime" ) )
9 years ago
{
9 years ago
SetHoldTime( atof( pkvd->szValue ) );
9 years ago
pkvd->fHandled = TRUE;
}
else
CPointEntity::KeyValue( pkvd );
}
void CFade::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
int fadeFlags = 0;
9 years ago
if( !( pev->spawnflags & SF_FADE_IN ) )
9 years ago
fadeFlags |= FFADE_OUT;
9 years ago
if( pev->spawnflags & SF_FADE_MODULATE )
9 years ago
fadeFlags |= FFADE_MODULATE;
9 years ago
if( pev->spawnflags & SF_FADE_ONLYONE )
9 years ago
{
9 years ago
if( pActivator->IsNetClient() )
9 years ago
{
UTIL_ScreenFade( pActivator, pev->rendercolor, Duration(), HoldTime(), (int)pev->renderamt, fadeFlags );
9 years ago
}
}
else
{
UTIL_ScreenFadeAll( pev->rendercolor, Duration(), HoldTime(), (int)pev->renderamt, fadeFlags );
9 years ago
}
SUB_UseTargets( this, USE_TOGGLE, 0 );
}
class CMessage : public CPointEntity
{
public:
9 years ago
void Spawn( void );
void Precache( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
void KeyValue( KeyValueData *pkvd );
9 years ago
private:
};
LINK_ENTITY_TO_CLASS( env_message, CMessage )
9 years ago
void CMessage::Spawn( void )
{
Precache();
9 years ago
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
9 years ago
switch( pev->impulse )
{
9 years ago
case 1:
// Medium radius
9 years ago
pev->speed = ATTN_STATIC;
break;
9 years ago
case 2:
// Large radius
9 years ago
pev->speed = ATTN_NORM;
break;
9 years ago
case 3:
//EVERYWHERE
9 years ago
pev->speed = ATTN_NONE;
break;
default:
case 0: // Small radius
pev->speed = ATTN_IDLE;
break;
}
pev->impulse = 0;
// No volume, use normal
if( pev->scale <= 0.0f )
pev->scale = 1.0f;
9 years ago
}
void CMessage::Precache( void )
{
9 years ago
if( pev->noise )
PRECACHE_SOUND( STRING( pev->noise ) );
9 years ago
}
void CMessage::KeyValue( KeyValueData *pkvd )
{
9 years ago
if( FStrEq( pkvd->szKeyName, "messagesound" ) )
9 years ago
{
9 years ago
pev->noise = ALLOC_STRING( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq(pkvd->szKeyName, "messagevolume" ) )
9 years ago
{
9 years ago
pev->scale = atof( pkvd->szValue ) * 0.1;
9 years ago
pkvd->fHandled = TRUE;
}
9 years ago
else if( FStrEq( pkvd->szKeyName, "messageattenuation" ) )
9 years ago
{
9 years ago
pev->impulse = atoi( pkvd->szValue );
9 years ago
pkvd->fHandled = TRUE;
}
else
CPointEntity::KeyValue( pkvd );
}
void CMessage::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
CBaseEntity *pPlayer = NULL;
9 years ago
if( pev->spawnflags & SF_MESSAGE_ALL )
UTIL_ShowMessageAll( STRING( pev->message ) );
9 years ago
else
{
9 years ago
if( pActivator && pActivator->IsPlayer() )
9 years ago
pPlayer = pActivator;
else
pPlayer = CBaseEntity::Instance( g_engfuncs.pfnPEntityOfEntIndex( 1 ) );
9 years ago
if( pPlayer )
UTIL_ShowMessage( STRING( pev->message ), pPlayer );
9 years ago
}
9 years ago
if( pev->noise )
EMIT_SOUND( edict(), CHAN_BODY, STRING( pev->noise ), pev->scale, pev->speed );
9 years ago
if( pev->spawnflags & SF_MESSAGE_ONCE )
9 years ago
UTIL_Remove( this );
SUB_UseTargets( this, USE_TOGGLE, 0 );
}
//=========================================================
// FunnelEffect
//=========================================================
class CEnvFunnel : public CBaseDelay
{
public:
9 years ago
void Spawn( void );
void Precache( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
9 years ago
9 years ago
int m_iSprite; // Don't save, precache
9 years ago
};
9 years ago
void CEnvFunnel::Precache( void )
9 years ago
{
m_iSprite = PRECACHE_MODEL( "sprites/flare6.spr" );
9 years ago
}
LINK_ENTITY_TO_CLASS( env_funnel, CEnvFunnel )
9 years ago
void CEnvFunnel::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE( TE_LARGEFUNNEL );
WRITE_COORD( pev->origin.x );
WRITE_COORD( pev->origin.y );
WRITE_COORD( pev->origin.z );
WRITE_SHORT( m_iSprite );
9 years ago
if( pev->spawnflags & SF_FUNNEL_REVERSE )// funnel flows in reverse?
9 years ago
{
WRITE_SHORT( 1 );
}
else
{
WRITE_SHORT( 0 );
}
MESSAGE_END();
SetThink( &CBaseEntity::SUB_Remove );
pev->nextthink = gpGlobals->time;
}
void CEnvFunnel::Spawn( void )
{
Precache();
pev->solid = SOLID_NOT;
pev->effects = EF_NODRAW;
}
//=========================================================
// Beverage Dispenser
// overloaded pev->frags, is now a flag for whether or not a can is stuck in the dispenser.
// overloaded pev->health, is now how many cans remain in the machine.
//=========================================================
class CEnvBeverage : public CBaseDelay
{
public:
9 years ago
void Spawn( void );
void Precache( void );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
9 years ago
};
9 years ago
void CEnvBeverage::Precache( void )
9 years ago
{
PRECACHE_MODEL( "models/can.mdl" );
PRECACHE_SOUND( "weapons/g_bounce3.wav" );
}
LINK_ENTITY_TO_CLASS( env_beverage, CEnvBeverage )
9 years ago
void CEnvBeverage::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
9 years ago
if( pev->frags != 0 || pev->health <= 0 )
9 years ago
{
// no more cans while one is waiting in the dispenser, or if I'm out of cans.
return;
}
CBaseEntity *pCan = CBaseEntity::Create( "item_sodacan", pev->origin, pev->angles, edict() );
9 years ago
if( pev->skin == 6 )
9 years ago
{
// random
pCan->pev->skin = RANDOM_LONG( 0, 5 );
}
else
{
pCan->pev->skin = pev->skin;
}
pev->frags = 1;
pev->health--;
9 years ago
//SetThink( &SUB_Remove );
9 years ago
//pev->nextthink = gpGlobals->time;
}
void CEnvBeverage::Spawn( void )
{
Precache();
pev->solid = SOLID_NOT;
pev->effects = EF_NODRAW;
pev->frags = 0;
9 years ago
if( pev->health == 0 )
9 years ago
{
pev->health = 10;
}
}
//=========================================================
// Soda can
//=========================================================
class CItemSoda : public CBaseEntity
{
public:
9 years ago
void Spawn( void );
void Precache( void );
void EXPORT CanThink( void );
void EXPORT CanTouch( CBaseEntity *pOther );
9 years ago
};
9 years ago
void CItemSoda::Precache( void )
9 years ago
{
PRECACHE_MODEL( "models/can.mdl" );
PRECACHE_SOUND( "weapons/g_bounce3.wav" );
9 years ago
}
LINK_ENTITY_TO_CLASS( item_sodacan, CItemSoda )
9 years ago
void CItemSoda::Spawn( void )
{
Precache();
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_TOSS;
9 years ago
SET_MODEL( ENT( pev ), "models/can.mdl" );
UTIL_SetSize( pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 ) );
9 years ago
9 years ago
SetThink( &CItemSoda::CanThink );
pev->nextthink = gpGlobals->time + 0.5f;
9 years ago
}
9 years ago
void CItemSoda::CanThink( void )
9 years ago
{
9 years ago
EMIT_SOUND( ENT( pev ), CHAN_WEAPON, "weapons/g_bounce3.wav", 1, ATTN_NORM );
9 years ago
pev->solid = SOLID_TRIGGER;
9 years ago
UTIL_SetSize( pev, Vector( -8, -8, 0 ), Vector( 8, 8, 8 ) );
9 years ago
SetThink( NULL );
SetTouch( &CItemSoda::CanTouch );
}
9 years ago
void CItemSoda::CanTouch( CBaseEntity *pOther )
9 years ago
{
9 years ago
if( !pOther->IsPlayer() )
9 years ago
{
return;
}
// spoit sound here
pOther->TakeHealth( 1, DMG_GENERIC );// a bit of health.
9 years ago
if( !FNullEnt( pev->owner ) )
9 years ago
{
// tell the machine the can was taken
pev->owner->v.frags = 0;
}
pev->solid = SOLID_NOT;
pev->movetype = MOVETYPE_NONE;
pev->effects = EF_NODRAW;
SetTouch( NULL );
SetThink( &CBaseEntity::SUB_Remove );
pev->nextthink = gpGlobals->time;
}