From 8a93caeb2828fecd90e276747ad6dca3c6ac74eb Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin Date: Sat, 6 Jun 2020 22:54:49 +0500 Subject: [PATCH] Rework env_random_shooter code. --- dlls/noffice/random_shooter.cpp | 232 +++++++++++++++++++++++++------- 1 file changed, 185 insertions(+), 47 deletions(-) diff --git a/dlls/noffice/random_shooter.cpp b/dlls/noffice/random_shooter.cpp index cf9080c2..4e21f10b 100644 --- a/dlls/noffice/random_shooter.cpp +++ b/dlls/noffice/random_shooter.cpp @@ -23,20 +23,6 @@ #include "func_break.h" #include "shake.h" -#define RANDOM_SHOOTER_INTERVAL_MIN 10 -#define RANDOM_SHOOTER_INTERVAL_MAX 15 - -#define RANDOM_SHOOTER_CAPACITY_MIN 1 -#define RANDOM_SHOOTER_CAPACITY_MAX 4 - -#define RANDOM_SHOOTER_VARIANCE_MIN 0.15 -#define RANDOM_SHOOTER_VARIANCE_MAX 0.5 - -#define RANDOM_SHOOTER_VELOCITY_MIN 150 -#define RANDOM_SHOOTER_VELOCITY_MAX 200 - -#define SF_RANDOMSHOOTER_REPEATABLE 1 // allows a env_random_shooter to be refired - // ========================================== // Code changes for- Night at the Office: // ========================================== @@ -45,76 +31,228 @@ // of env_shooter only this fires repeatedly in bursts, // so one entity can be used instead of many env_shooters. -class CRandomShooter : public CEnvShooter +class CGibShooter2 : public CBaseDelay { - void Spawn(void); - void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); +public: + void Spawn(); + void Precache(); + void KeyValue( KeyValueData *pkvd ); + void EXPORT ShootThink(); + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT RandomThink(void); -}; + virtual CGib *CreateGib(); + + virtual int Save( CSave &save ); + virtual int Restore( CRestore &restore ); + static TYPEDESCRIPTION m_SaveData[]; -LINK_ENTITY_TO_CLASS(env_random_shooter, CRandomShooter); + int m_iGibs; + int m_iGibCapacity; + int m_iGibMaterial; + int m_iGibModelIndex; + float m_flGibVelocity; + float m_flVariance; + float m_flGibLife; +}; -void CRandomShooter::Spawn(void) +TYPEDESCRIPTION CGibShooter2::m_SaveData[] = { - CEnvShooter::Spawn(); + DEFINE_FIELD( CGibShooter2, m_iGibs, FIELD_INTEGER ), + DEFINE_FIELD( CGibShooter2, m_iGibCapacity, FIELD_INTEGER ), + DEFINE_FIELD( CGibShooter2, m_iGibMaterial, FIELD_INTEGER ), + DEFINE_FIELD( CGibShooter2, m_iGibModelIndex, FIELD_INTEGER ), + DEFINE_FIELD( CGibShooter2, m_flGibVelocity, FIELD_FLOAT ), + DEFINE_FIELD( CGibShooter2, m_flVariance, FIELD_FLOAT ), + DEFINE_FIELD( CGibShooter2, m_flGibLife, FIELD_FLOAT ), +}; - SetThink( NULL ); +IMPLEMENT_SAVERESTORE( CGibShooter2, CBaseDelay ) + +void CGibShooter2::Precache( void ) +{ + m_iGibModelIndex = PRECACHE_MODEL( "models/hgibs.mdl" ); } -void CRandomShooter::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) +void CGibShooter2::KeyValue( KeyValueData *pkvd ) { - SetThink(&CRandomShooter::RandomThink); + if( FStrEq( pkvd->szKeyName, "m_flVelocity" ) ) + { + m_flGibVelocity = atof( pkvd->szValue ); + pkvd->fHandled = TRUE; + } + else + { + CBaseDelay::KeyValue( pkvd ); + } +} +void CGibShooter2::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) +{ + SetThink( &CGibShooter2::ShootThink ); pev->nextthink = gpGlobals->time; } -void CRandomShooter::RandomThink(void) +void CGibShooter2::Spawn( void ) +{ + Precache(); + + pev->solid = SOLID_NOT; + pev->effects = EF_NODRAW; + + if( m_flDelay == 0 ) + { + m_flDelay = 0.1; + } + + m_flGibLife = 6; + m_iGibs = m_iGibCapacity = RANDOM_LONG( 2, 6 ); + + SetMovedir( pev ); + pev->body = MODEL_FRAMES( m_iGibModelIndex ); +} + +CGib *CGibShooter2::CreateGib( void ) +{ + if( CVAR_GET_FLOAT( "violence_hgibs" ) == 0 ) + return NULL; + + CGib *pGib = GetClassPtr( (CGib *)NULL ); + pGib->Spawn( "models/hgibs.mdl" ); + pGib->m_bloodColor = BLOOD_COLOR_RED; + + if( pev->body <= 1 ) + { + ALERT( at_aiconsole, "GibShooter2 Body is <= 1!\n" ); + } + + pGib->pev->body = RANDOM_LONG( 1, pev->body - 1 );// avoid throwing random amounts of the 0th gib. (skull). + + return pGib; +} + +void CGibShooter2::ShootThink( void ) { + m_flDelay = RANDOM_FLOAT( 0.1f, 0.4f ); + + pev->nextthink = gpGlobals->time + m_flDelay; + + m_flVariance = RANDOM_FLOAT( 0.1f, 0.3f ); + Vector vecShootDir; vecShootDir = pev->movedir; - vecShootDir = vecShootDir + gpGlobals->v_right * RANDOM_FLOAT(-1, 1) * m_flVariance;; - vecShootDir = vecShootDir + gpGlobals->v_forward * RANDOM_FLOAT(-1, 1) * m_flVariance;; - vecShootDir = vecShootDir + gpGlobals->v_up * RANDOM_FLOAT(-1, 1) * m_flVariance;; + 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; vecShootDir = vecShootDir.Normalize(); CGib *pGib = CreateGib(); - - if (pGib) + + if( pGib ) { - if (FStrEq(STRING(pGib->pev->model), "models/rocks.mdl")) - { - pGib->pev->body = RANDOM_LONG(0, 3); - } - pGib->pev->origin = pev->origin; pGib->pev->velocity = vecShootDir * m_flGibVelocity; - pGib->pev->avelocity.x = RANDOM_FLOAT(100, 200); - pGib->pev->avelocity.y = RANDOM_FLOAT(100, 300); + pGib->pev->avelocity.x = RANDOM_FLOAT( 100.0f, 200.0f ); + pGib->pev->avelocity.y = RANDOM_FLOAT( 100.0f, 300.0f ); float thinkTime = pGib->pev->nextthink - gpGlobals->time; - pGib->m_lifeTime = (m_flGibLife * RANDOM_FLOAT(0.95, 1.05)); // +/- 5% - if (pGib->m_lifeTime < thinkTime) + pGib->m_lifeTime = ( m_flGibLife * RANDOM_FLOAT( 0.95f, 1.05f ) ); // +/- 5% + if( pGib->m_lifeTime < thinkTime ) { pGib->pev->nextthink = gpGlobals->time + pGib->m_lifeTime; pGib->m_lifeTime = 0; } } - if (--m_iGibs <= 0) + if( --m_iGibs <= 0 ) { - m_iGibs = RANDOM_LONG (RANDOM_SHOOTER_CAPACITY_MIN, RANDOM_SHOOTER_CAPACITY_MAX); - m_flGibVelocity = RANDOM_FLOAT(RANDOM_SHOOTER_VELOCITY_MIN, RANDOM_SHOOTER_VELOCITY_MAX); - m_flVariance = RANDOM_FLOAT(RANDOM_SHOOTER_VARIANCE_MIN, RANDOM_SHOOTER_VARIANCE_MAX); + m_iGibs = m_iGibCapacity; + pev->nextthink = gpGlobals->time + RANDOM_FLOAT( 8.0f, 21.0f ); + } +} + +class CEnvRandomShooter : public CGibShooter2 +{ +public: + void Precache(); + void KeyValue( KeyValueData *pkvd ); + + CGib *CreateGib( void ); +}; - pev->nextthink = gpGlobals->time + RANDOM_FLOAT(RANDOM_SHOOTER_INTERVAL_MIN, RANDOM_SHOOTER_INTERVAL_MAX); +LINK_ENTITY_TO_CLASS( env_random_shooter, CEnvRandomShooter ) + +void CEnvRandomShooter::KeyValue( KeyValueData *pkvd ) +{ + if( FStrEq( pkvd->szKeyName, "shootmodel" ) ) + { + pev->model = ALLOC_STRING( pkvd->szValue ); + pkvd->fHandled = TRUE; + } + else if ( FStrEq( pkvd->szKeyName, "shootsounds" ) ) + { + int iNoise = atoi( pkvd->szValue ); + 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 { - pev->nextthink = gpGlobals->time; + CGibShooter2::KeyValue( pkvd ); } -} \ No newline at end of file +} + +void CEnvRandomShooter::Precache( void ) +{ + m_iGibModelIndex = PRECACHE_MODEL( STRING( pev->model ) ); + CBreakable::MaterialSoundPrecache( (Materials)m_iGibMaterial ); +} + +CGib *CEnvRandomShooter::CreateGib( void ) +{ + CGib *pGib = GetClassPtr( (CGib *)NULL ); + + pGib->Spawn( STRING( pev->model ) ); + + int bodyPart = 0; + + if( pev->body > 1 ) + bodyPart = RANDOM_LONG( 0, pev->body - 1 ); + + 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; +} +