reorder folders
This commit is contained in:
446
src/dlls/effects.cpp
Normal file
446
src/dlls/effects.cpp
Normal file
@@ -0,0 +1,446 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#include "cmbase.h"
|
||||
#include "cmbasemonster.h"
|
||||
#include "monsters.h"
|
||||
#include "customentity.h"
|
||||
#include "effects.h"
|
||||
#include "weapons.h"
|
||||
#include "decals.h"
|
||||
#include "func_break.h"
|
||||
#include "shake.h"
|
||||
|
||||
#define SF_GIBSHOOTER_REPEATABLE 1 // allows a gibshooter to be refired
|
||||
|
||||
#define SF_FUNNEL_REVERSE 1 // funnel effect repels particles instead of attracting them.
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
//
|
||||
// Beams
|
||||
//
|
||||
// --------------------------------------------------
|
||||
|
||||
void CMBeam::Spawn( void )
|
||||
{
|
||||
pev->solid = SOLID_NOT; // Remove model & collisions
|
||||
Precache( );
|
||||
}
|
||||
|
||||
void CMBeam::Precache( void )
|
||||
{
|
||||
if ( pev->owner )
|
||||
SetStartEntity( ENTINDEX( pev->owner ) );
|
||||
if ( pev->aiment )
|
||||
SetEndEntity( ENTINDEX( pev->aiment ) );
|
||||
}
|
||||
|
||||
void CMBeam::SetStartEntity( int entityIndex )
|
||||
{
|
||||
pev->sequence = (entityIndex & 0x0FFF) | ((pev->sequence&0xF000)<<12);
|
||||
pev->owner = g_engfuncs.pfnPEntityOfEntIndex( entityIndex );
|
||||
}
|
||||
|
||||
void CMBeam::SetEndEntity( int entityIndex )
|
||||
{
|
||||
pev->skin = (entityIndex & 0x0FFF) | ((pev->skin&0xF000)<<12);
|
||||
pev->aiment = g_engfuncs.pfnPEntityOfEntIndex( entityIndex );
|
||||
}
|
||||
|
||||
|
||||
// These don't take attachments into account
|
||||
const Vector &CMBeam::GetStartPos( void )
|
||||
{
|
||||
if ( GetType() == BEAM_ENTS )
|
||||
{
|
||||
edict_t *pent = g_engfuncs.pfnPEntityOfEntIndex( GetStartEntity() );
|
||||
return pent->v.origin;
|
||||
}
|
||||
return pev->origin;
|
||||
}
|
||||
|
||||
|
||||
const Vector &CMBeam::GetEndPos( void )
|
||||
{
|
||||
int type = GetType();
|
||||
if ( type == BEAM_POINTS || type == BEAM_HOSE )
|
||||
{
|
||||
return pev->angles;
|
||||
}
|
||||
|
||||
edict_t *pent = g_engfuncs.pfnPEntityOfEntIndex( GetEndEntity() );
|
||||
if ( pent )
|
||||
return pent->v.origin;
|
||||
return pev->angles;
|
||||
}
|
||||
|
||||
|
||||
CMBeam *CMBeam::BeamCreate( const char *pSpriteName, int width )
|
||||
{
|
||||
// Create a new entity with CMBeam private data
|
||||
CMBeam *pBeam = CreateClassPtr( (CMBeam *)NULL );
|
||||
|
||||
if (pBeam == NULL)
|
||||
return NULL;
|
||||
|
||||
pBeam->pev->classname = MAKE_STRING("beam");
|
||||
|
||||
pBeam->BeamInit( pSpriteName, width );
|
||||
|
||||
return pBeam;
|
||||
}
|
||||
|
||||
|
||||
void CMBeam::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( (char *)pSpriteName ) );
|
||||
SetWidth( width );
|
||||
pev->skin = 0;
|
||||
pev->sequence = 0;
|
||||
pev->rendermode = 0;
|
||||
}
|
||||
|
||||
|
||||
void CMBeam::PointsInit( const Vector &start, const Vector &end )
|
||||
{
|
||||
SetType( BEAM_POINTS );
|
||||
SetStartPos( start );
|
||||
SetEndPos( end );
|
||||
SetStartAttachment( 0 );
|
||||
SetEndAttachment( 0 );
|
||||
RelinkBeam();
|
||||
}
|
||||
|
||||
|
||||
void CMBeam::HoseInit( const Vector &start, const Vector &direction )
|
||||
{
|
||||
SetType( BEAM_HOSE );
|
||||
SetStartPos( start );
|
||||
SetEndPos( direction );
|
||||
SetStartAttachment( 0 );
|
||||
SetEndAttachment( 0 );
|
||||
RelinkBeam();
|
||||
}
|
||||
|
||||
|
||||
void CMBeam::PointEntInit( const Vector &start, int endIndex )
|
||||
{
|
||||
SetType( BEAM_ENTPOINT );
|
||||
SetStartPos( start );
|
||||
SetEndEntity( endIndex );
|
||||
SetStartAttachment( 0 );
|
||||
SetEndAttachment( 0 );
|
||||
RelinkBeam();
|
||||
}
|
||||
|
||||
void CMBeam::EntsInit( int startIndex, int endIndex )
|
||||
{
|
||||
SetType( BEAM_ENTS );
|
||||
SetStartEntity( startIndex );
|
||||
SetEndEntity( endIndex );
|
||||
SetStartAttachment( 0 );
|
||||
SetEndAttachment( 0 );
|
||||
RelinkBeam();
|
||||
}
|
||||
|
||||
|
||||
void CMBeam::RelinkBeam( void )
|
||||
{
|
||||
const Vector &startPos = GetStartPos(), &endPos = GetEndPos();
|
||||
|
||||
pev->mins.x = min( startPos.x, endPos.x );
|
||||
pev->mins.y = min( startPos.y, endPos.y );
|
||||
pev->mins.z = min( startPos.z, endPos.z );
|
||||
pev->maxs.x = max( startPos.x, endPos.x );
|
||||
pev->maxs.y = max( startPos.y, endPos.y );
|
||||
pev->maxs.z = max( startPos.z, endPos.z );
|
||||
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 CMBeam::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 CMBeam::TriggerTouch( edict_t *pOther )
|
||||
{
|
||||
if ( pOther->v.flags & (FL_CLIENT | FL_MONSTER) )
|
||||
{
|
||||
if ( pev->owner )
|
||||
{
|
||||
if (pev->owner->v.euser4 != NULL)
|
||||
{
|
||||
CMBaseEntity *pOwner = GetClassPtr((CMBaseEntity *)VARS(pev->owner));
|
||||
pOwner->Use( pOther, this->edict(), USE_TOGGLE, 0 );
|
||||
}
|
||||
}
|
||||
ALERT( at_console, "Firing targets!!!\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
edict_t *CMBeam::RandomTargetname( const char *szName )
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
edict_t *pEntity = NULL;
|
||||
edict_t *pNewEntity = NULL;
|
||||
while ((pNewEntity = UTIL_FindEntityByTargetname( pNewEntity, szName )) != NULL)
|
||||
{
|
||||
total++;
|
||||
if (RANDOM_LONG(0,total-1) < 1)
|
||||
pEntity = pNewEntity;
|
||||
}
|
||||
return pEntity;
|
||||
}
|
||||
|
||||
|
||||
void CMBeam::DoSparks( const Vector &start, const Vector &end )
|
||||
{
|
||||
if ( pev->spawnflags & (SF_BEAM_SPARKSTART|SF_BEAM_SPARKEND) )
|
||||
{
|
||||
if ( pev->spawnflags & SF_BEAM_SPARKSTART )
|
||||
{
|
||||
UTIL_Sparks( start );
|
||||
}
|
||||
if ( pev->spawnflags & SF_BEAM_SPARKEND )
|
||||
{
|
||||
UTIL_Sparks( end );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMBeam::BeamDamage( TraceResult *ptr )
|
||||
{
|
||||
RelinkBeam();
|
||||
if ( ptr->flFraction != 1.0 && ptr->pHit != NULL )
|
||||
{
|
||||
if (UTIL_IsPlayer(ptr->pHit))
|
||||
{
|
||||
ClearMultiDamage();
|
||||
UTIL_TraceAttack(ptr->pHit, pev, pev->dmg * (gpGlobals->time - pev->dmgtime), (ptr->vecEndPos - pev->origin).Normalize(), ptr, DMG_ENERGYBEAM );
|
||||
ApplyMultiDamage( pev, pev );
|
||||
|
||||
if ( pev->spawnflags & SF_BEAM_DECALS )
|
||||
{
|
||||
if ( UTIL_IsBSPModel(ptr->pHit) )
|
||||
UTIL_DecalTrace( ptr, DECAL_BIGSHOT1 + RANDOM_LONG(0,4) );
|
||||
}
|
||||
|
||||
}
|
||||
else if (ptr->pHit->v.euser4 != NULL)
|
||||
{
|
||||
ClearMultiDamage();
|
||||
CMBaseEntity *pMonster = GetClassPtr((CMBaseEntity *)VARS(ptr->pHit));
|
||||
pMonster->TraceAttack( pev, pev->dmg * (gpGlobals->time - pev->dmgtime), (ptr->vecEndPos - pev->origin).Normalize(), ptr, DMG_ENERGYBEAM );
|
||||
ApplyMultiDamage( pev, pev );
|
||||
|
||||
if ( pev->spawnflags & SF_BEAM_DECALS )
|
||||
{
|
||||
if ( pMonster->IsBSPModel() )
|
||||
UTIL_DecalTrace( ptr, DECAL_BIGSHOT1 + RANDOM_LONG(0,4) );
|
||||
}
|
||||
}
|
||||
}
|
||||
pev->dmgtime = gpGlobals->time;
|
||||
}
|
||||
|
||||
|
||||
void CMSprite::Spawn( void )
|
||||
{
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->movetype = MOVETYPE_NONE;
|
||||
pev->effects = 0;
|
||||
pev->frame = 0;
|
||||
|
||||
Precache();
|
||||
SET_MODEL( ENT(pev), STRING(pev->model) );
|
||||
|
||||
m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1;
|
||||
if ( pev->targetname && !(pev->spawnflags & SF_SPRITE_STARTON) )
|
||||
TurnOff();
|
||||
else
|
||||
TurnOn();
|
||||
|
||||
// Worldcraft only sets y rotation, copy to Z
|
||||
if ( pev->angles.y != 0 && pev->angles.z == 0 )
|
||||
{
|
||||
pev->angles.z = pev->angles.y;
|
||||
pev->angles.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CMSprite::Precache( void )
|
||||
{
|
||||
PRECACHE_MODEL( (char *)STRING(pev->model) );
|
||||
|
||||
// Reset attachment after save/restore
|
||||
if ( pev->aiment )
|
||||
SetAttachment( pev->aiment, pev->body );
|
||||
else
|
||||
{
|
||||
// Clear attachment
|
||||
pev->skin = 0;
|
||||
pev->body = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CMSprite::SpriteInit( const char *pSpriteName, const Vector &origin )
|
||||
{
|
||||
pev->model = MAKE_STRING(pSpriteName);
|
||||
pev->origin = origin;
|
||||
Spawn();
|
||||
}
|
||||
|
||||
CMSprite *CMSprite::SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate )
|
||||
{
|
||||
CMSprite *pSprite = CreateClassPtr( (CMSprite *)NULL );
|
||||
pSprite->SpriteInit( pSpriteName, origin );
|
||||
pSprite->pev->classname = MAKE_STRING("env_sprite");
|
||||
pSprite->pev->solid = SOLID_NOT;
|
||||
pSprite->pev->movetype = MOVETYPE_NOCLIP;
|
||||
if ( animate )
|
||||
pSprite->TurnOn();
|
||||
|
||||
return pSprite;
|
||||
}
|
||||
|
||||
|
||||
void CMSprite::AnimateThink( void )
|
||||
{
|
||||
Animate( pev->framerate * (gpGlobals->time - m_lastTime) );
|
||||
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
m_lastTime = gpGlobals->time;
|
||||
}
|
||||
|
||||
void CMSprite::AnimateUntilDead( void )
|
||||
{
|
||||
if ( gpGlobals->time > pev->dmgtime )
|
||||
UTIL_Remove(this->edict());
|
||||
else
|
||||
{
|
||||
AnimateThink();
|
||||
pev->nextthink = gpGlobals->time;
|
||||
}
|
||||
}
|
||||
|
||||
void CMSprite::Expand( float scaleSpeed, float fadeSpeed )
|
||||
{
|
||||
pev->speed = scaleSpeed;
|
||||
pev->health = fadeSpeed;
|
||||
SetThink( ExpandThink );
|
||||
|
||||
pev->nextthink = gpGlobals->time;
|
||||
m_lastTime = gpGlobals->time;
|
||||
}
|
||||
|
||||
|
||||
void CMSprite::ExpandThink( void )
|
||||
{
|
||||
float frametime = gpGlobals->time - m_lastTime;
|
||||
pev->scale += pev->speed * frametime;
|
||||
pev->renderamt -= pev->health * frametime;
|
||||
if ( pev->renderamt <= 0 )
|
||||
{
|
||||
pev->renderamt = 0;
|
||||
UTIL_Remove( this->edict() );
|
||||
}
|
||||
else
|
||||
{
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
m_lastTime = gpGlobals->time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CMSprite::Animate( float frames )
|
||||
{
|
||||
pev->frame += frames;
|
||||
if ( pev->frame > m_maxFrame )
|
||||
{
|
||||
if ( pev->spawnflags & SF_SPRITE_ONCE )
|
||||
{
|
||||
TurnOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_maxFrame > 0 )
|
||||
pev->frame = fmod( pev->frame, m_maxFrame );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CMSprite::TurnOff( void )
|
||||
{
|
||||
pev->effects = EF_NODRAW;
|
||||
pev->nextthink = 0;
|
||||
}
|
||||
|
||||
|
||||
void CMSprite::TurnOn( void )
|
||||
{
|
||||
pev->effects = 0;
|
||||
if ( (pev->framerate && m_maxFrame > 1.0) || (pev->spawnflags & SF_SPRITE_ONCE) )
|
||||
{
|
||||
SetThink( AnimateThink );
|
||||
pev->nextthink = gpGlobals->time;
|
||||
m_lastTime = gpGlobals->time;
|
||||
}
|
||||
pev->frame = 0;
|
||||
}
|
||||
|
||||
|
||||
void CMSprite::Use( edict_t *pActivator, edict_t *pCaller, USE_TYPE useType, float value )
|
||||
{
|
||||
int on = pev->effects != EF_NODRAW;
|
||||
if ( ShouldToggle( useType, on ) )
|
||||
{
|
||||
if ( on )
|
||||
{
|
||||
TurnOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
TurnOn();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user