diff --git a/dlls/prop.cpp b/dlls/prop.cpp index 56671736..f87edf5a 100644 --- a/dlls/prop.cpp +++ b/dlls/prop.cpp @@ -39,1108 +39,1113 @@ typedef enum { matGlass = 0, matWood, matMetal, matFlesh, matCinderBlock, matCei //extern "C" void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); Vector UTIL_AngleVectorsF(const Vector &angles) { - float rgflVecOut[3]; - float rgflVecIn[3]; - angles.CopyToArray(rgflVecIn); - g_engfuncs.pfnAngleVectors(rgflVecIn, rgflVecOut, NULL, NULL); - return Vector(rgflVecOut); + float rgflVecOut[3]; + float rgflVecIn[3]; + angles.CopyToArray(rgflVecIn); + g_engfuncs.pfnAngleVectors(rgflVecIn, rgflVecOut, NULL, NULL); + return Vector(rgflVecOut); } Vector UTIL_AngleVectorsR(const Vector &angles) { - float rgflVecOut[3]; - float rgflVecIn[3]; - angles.CopyToArray(rgflVecIn); - g_engfuncs.pfnAngleVectors(rgflVecIn, NULL, rgflVecOut, NULL); - return Vector(rgflVecOut); + float rgflVecOut[3]; + float rgflVecIn[3]; + angles.CopyToArray(rgflVecIn); + g_engfuncs.pfnAngleVectors(rgflVecIn, NULL, rgflVecOut, NULL); + return Vector(rgflVecOut); } Vector UTIL_AngleVectorsU(const Vector &angles) { - float rgflVecOut[3]; - float rgflVecIn[3]; - angles.CopyToArray(rgflVecIn); - g_engfuncs.pfnAngleVectors(rgflVecIn, NULL, rgflVecOut, NULL); - return Vector(rgflVecOut); + float rgflVecOut[3]; + float rgflVecIn[3]; + angles.CopyToArray(rgflVecIn); + g_engfuncs.pfnAngleVectors(rgflVecIn, NULL, rgflVecOut, NULL); + return Vector(rgflVecOut); } //===================grenade enum PropShape { - SHAPE_CYL_H = 0, - SHAPE_CYL_V, - SHAPE_BOX, - SHAPE_GENERIC, - SHAPE_SPHERE, - SHAPE_NOROTATE + SHAPE_CYL_H = 0, + SHAPE_CYL_V, + SHAPE_BOX, + SHAPE_GENERIC, + SHAPE_SPHERE, + SHAPE_NOROTATE }; class CProp : public CBaseEntity { public: - void Spawn(void); - void Precache(); - - void EXPORT BounceTouch(CBaseEntity *pOther); - //void EXPORT SlideTouch(CBaseEntity *pOther); - virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); - virtual void Force(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); - int TakeDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType); - virtual int ObjectCaps(void) { return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE | FCAP_CONTINUOUS_USE; } - virtual void BounceSound(void); - virtual int BloodColor(void) { return DONT_BLEED; } - virtual void Killed(entvars_t *pevAttacker, int iGib); - void CheckRotate(); - void RespawnThink(); - void AngleThink(); - void DeployThink(); - void DamageSound( void ); - void PropRespawn(); - void KeyValue( KeyValueData* pkvd); - - static const char *pSoundsWood[]; - static const char *pSoundsFlesh[]; - static const char *pSoundsGlass[]; - static const char *pSoundsMetal[]; - static const char *pSoundsConcrete[]; - static const char *pSpawnObjects[]; - - inline BOOL Explodable( void ) { return ExplosionMagnitude() > 0; } - inline int ExplosionMagnitude( void ) { return pev->impulse; } - inline void ExplosionSetMagnitude( int magnitude ) { pev->impulse = magnitude; } - - - static void MaterialSoundPrecache( Materials precacheMaterial ); - static void MaterialSoundRandom( edict_t *pEdict, Materials soundMaterial, float volume ); - static const char **MaterialSoundList( Materials precacheMaterial, int &soundCount ); - void EXPORT Die( void ); - - BOOL m_bBarrel; - float m_flFloorFriction; - float m_flCollideFriction; - - // hull sizes - Vector minsH, maxsH; - Vector minsV, maxsV; - - // spawn backup; - Vector spawnOrigin; - Vector spawnAngles; - - edict_t *m_owner2; - edict_t *m_attacker; - float m_flNextAttack; - float m_flRespawnTime; - PropShape m_shape; - PropShape m_oldshape; - CBasePlayer *m_pHolstered; - float m_flSpawnHealth; - int m_idShard; - float m_angle; - int m_iszGibModel; - Materials m_Material; - Explosions m_Explosion; - int m_iaCustomAnglesX[10]; - int m_iaCustomAnglesZ[10]; + void Spawn(void); + void Precache(); + + void EXPORT BounceTouch(CBaseEntity *pOther); + //void EXPORT SlideTouch(CBaseEntity *pOther); + virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); + virtual void Force(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value); + int TakeDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType); + virtual int ObjectCaps(void) { return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE | FCAP_CONTINUOUS_USE; } + virtual void BounceSound(void); + virtual int BloodColor(void) { return DONT_BLEED; } + virtual void Killed(entvars_t *pevAttacker, int iGib); + void CheckRotate(); + void RespawnThink(); + void AngleThink(); + void DeployThink(); + void DamageSound( void ); + void PropRespawn(); + void KeyValue( KeyValueData* pkvd); + + static const char *pSoundsWood[]; + static const char *pSoundsFlesh[]; + static const char *pSoundsGlass[]; + static const char *pSoundsMetal[]; + static const char *pSoundsConcrete[]; + static const char *pSpawnObjects[]; + + inline BOOL Explodable( void ) { return ExplosionMagnitude() > 0; } + inline int ExplosionMagnitude( void ) { return pev->impulse; } + inline void ExplosionSetMagnitude( int magnitude ) { pev->impulse = magnitude; } + + + static void MaterialSoundPrecache( Materials precacheMaterial ); + static void MaterialSoundRandom( edict_t *pEdict, Materials soundMaterial, float volume ); + static const char **MaterialSoundList( Materials precacheMaterial, int &soundCount ); + void EXPORT Die( void ); + + BOOL m_bBarrel; + float m_flFloorFriction; + float m_flCollideFriction; + + // hull sizes + Vector minsH, maxsH; + Vector minsV, maxsV; + + // spawn backup; + Vector spawnOrigin; + Vector spawnAngles; + + edict_t *m_owner2; + edict_t *m_attacker; + float m_flNextAttack; + float m_flRespawnTime; + PropShape m_shape; + PropShape m_oldshape; + CBasePlayer *m_pHolstered; + float m_flSpawnHealth; + int m_idShard; + float m_angle; + int m_iszGibModel; + Materials m_Material; + Explosions m_Explosion; + int m_iaCustomAnglesX[10]; + int m_iaCustomAnglesZ[10]; }; LINK_ENTITY_TO_CLASS(prop, CProp); const char *CProp::pSoundsWood[] = { - "debris/wood1.wav", - "debris/wood2.wav", - "debris/wood3.wav", + "debris/wood1.wav", + "debris/wood2.wav", + "debris/wood3.wav", }; const char *CProp::pSoundsFlesh[] = { - "debris/flesh1.wav", - "debris/flesh2.wav", - "debris/flesh3.wav", - "debris/flesh5.wav", - "debris/flesh6.wav", - "debris/flesh7.wav", + "debris/flesh1.wav", + "debris/flesh2.wav", + "debris/flesh3.wav", + "debris/flesh5.wav", + "debris/flesh6.wav", + "debris/flesh7.wav", }; const char *CProp::pSoundsMetal[] = { - "debris/metal1.wav", - "debris/metal2.wav", - "debris/metal3.wav", + "debris/metal1.wav", + "debris/metal2.wav", + "debris/metal3.wav", }; const char *CProp::pSoundsConcrete[] = { - "debris/concrete1.wav", - "debris/concrete2.wav", - "debris/concrete3.wav", + "debris/concrete1.wav", + "debris/concrete2.wav", + "debris/concrete3.wav", }; const char *CProp::pSoundsGlass[] = { - "debris/glass1.wav", - "debris/glass2.wav", - "debris/glass3.wav", + "debris/glass1.wav", + "debris/glass2.wav", + "debris/glass3.wav", }; const char **CProp::MaterialSoundList( Materials precacheMaterial, int &soundCount ) { - const char **pSoundList = NULL; - - switch ( precacheMaterial ) - { - case matWood: - pSoundList = pSoundsWood; - soundCount = ARRAYSIZE(pSoundsWood); - break; - case matFlesh: - pSoundList = pSoundsFlesh; - soundCount = ARRAYSIZE(pSoundsFlesh); - break; - case matComputer: - case matUnbreakableGlass: - case matGlass: - pSoundList = pSoundsGlass; - soundCount = ARRAYSIZE(pSoundsGlass); - break; - - case matMetal: - pSoundList = pSoundsMetal; - soundCount = ARRAYSIZE(pSoundsMetal); - break; - - case matCinderBlock: - case matRocks: - pSoundList = pSoundsConcrete; - soundCount = ARRAYSIZE(pSoundsConcrete); - break; - - - case matCeilingTile: - case matNone: - default: - soundCount = 0; - break; - } - - return pSoundList; + const char **pSoundList = NULL; + + switch ( precacheMaterial ) + { + case matWood: + pSoundList = pSoundsWood; + soundCount = ARRAYSIZE(pSoundsWood); + break; + case matFlesh: + pSoundList = pSoundsFlesh; + soundCount = ARRAYSIZE(pSoundsFlesh); + break; + case matComputer: + case matUnbreakableGlass: + case matGlass: + pSoundList = pSoundsGlass; + soundCount = ARRAYSIZE(pSoundsGlass); + break; + + case matMetal: + pSoundList = pSoundsMetal; + soundCount = ARRAYSIZE(pSoundsMetal); + break; + + case matCinderBlock: + case matRocks: + pSoundList = pSoundsConcrete; + soundCount = ARRAYSIZE(pSoundsConcrete); + break; + + + case matCeilingTile: + case matNone: + default: + soundCount = 0; + break; + } + + return pSoundList; } void CProp::MaterialSoundPrecache( Materials precacheMaterial ) { - const char **pSoundList; - int i, soundCount = 0; + const char **pSoundList; + int i, soundCount = 0; - pSoundList = MaterialSoundList( precacheMaterial, soundCount ); + pSoundList = MaterialSoundList( precacheMaterial, soundCount ); - for ( i = 0; i < soundCount; i++ ) - { - PRECACHE_SOUND( (char *)pSoundList[i] ); - } + for ( i = 0; i < soundCount; i++ ) + { + PRECACHE_SOUND( (char *)pSoundList[i] ); + } } void CProp::MaterialSoundRandom( edict_t *pEdict, Materials soundMaterial, float volume ) { - const char **pSoundList; - int soundCount = 0; + const char **pSoundList; + int soundCount = 0; - pSoundList = MaterialSoundList( soundMaterial, soundCount ); + pSoundList = MaterialSoundList( soundMaterial, soundCount ); - if ( soundCount ) - EMIT_SOUND( pEdict, CHAN_BODY, pSoundList[ RANDOM_LONG(0,soundCount-1) ], volume, 1.0 ); + if ( soundCount ) + EMIT_SOUND( pEdict, CHAN_BODY, pSoundList[ RANDOM_LONG(0,soundCount-1) ], volume, 1.0 ); } void CProp::Precache( void ) { - const char *pGibName; - - switch (m_Material) - { - case matWood: - pGibName = "models/woodgibs.mdl"; - - PRECACHE_SOUND("debris/bustcrate1.wav"); - PRECACHE_SOUND("debris/bustcrate2.wav"); - break; - case matFlesh: - pGibName = "models/fleshgibs.mdl"; - - PRECACHE_SOUND("debris/bustflesh1.wav"); - PRECACHE_SOUND("debris/bustflesh2.wav"); - break; - case matComputer: - PRECACHE_SOUND("buttons/spark5.wav"); - PRECACHE_SOUND("buttons/spark6.wav"); - pGibName = "models/computergibs.mdl"; - - PRECACHE_SOUND("debris/bustmetal1.wav"); - PRECACHE_SOUND("debris/bustmetal2.wav"); - break; - - case matUnbreakableGlass: - case matGlass: - pGibName = "models/glassgibs.mdl"; - - PRECACHE_SOUND("debris/bustglass1.wav"); - PRECACHE_SOUND("debris/bustglass2.wav"); - break; - case matMetal: - pGibName = "models/metalplategibs.mdl"; - - PRECACHE_SOUND("debris/bustmetal1.wav"); - PRECACHE_SOUND("debris/bustmetal2.wav"); - break; - case matCinderBlock: - pGibName = "models/cindergibs.mdl"; - - PRECACHE_SOUND("debris/bustconcrete1.wav"); - PRECACHE_SOUND("debris/bustconcrete2.wav"); - break; - case matRocks: - pGibName = "models/rockgibs.mdl"; - - PRECACHE_SOUND("debris/bustconcrete1.wav"); - PRECACHE_SOUND("debris/bustconcrete2.wav"); - break; - case matCeilingTile: - pGibName = "models/ceilinggibs.mdl"; - - PRECACHE_SOUND ("debris/bustceiling.wav"); - break; - } - MaterialSoundPrecache( m_Material ); - if ( m_iszGibModel ) - pGibName = STRING(m_iszGibModel); - - m_idShard = PRECACHE_MODEL( (char *)pGibName ); - PRECACHE_MODEL( (char *)STRING(pev->model) ); + const char *pGibName; + + if( !pev->model ) + pev->model = MAKE_STRING( "models/xash/barrel_brown.mdl" ); + + switch (m_Material) + { + case matWood: + pGibName = "models/woodgibs.mdl"; + + PRECACHE_SOUND("debris/bustcrate1.wav"); + PRECACHE_SOUND("debris/bustcrate2.wav"); + break; + case matFlesh: + pGibName = "models/fleshgibs.mdl"; + + PRECACHE_SOUND("debris/bustflesh1.wav"); + PRECACHE_SOUND("debris/bustflesh2.wav"); + break; + case matComputer: + PRECACHE_SOUND("buttons/spark5.wav"); + PRECACHE_SOUND("buttons/spark6.wav"); + pGibName = "models/computergibs.mdl"; + + PRECACHE_SOUND("debris/bustmetal1.wav"); + PRECACHE_SOUND("debris/bustmetal2.wav"); + break; + + case matUnbreakableGlass: + case matGlass: + pGibName = "models/glassgibs.mdl"; + + PRECACHE_SOUND("debris/bustglass1.wav"); + PRECACHE_SOUND("debris/bustglass2.wav"); + break; + case matMetal: + pGibName = "models/metalplategibs.mdl"; + + PRECACHE_SOUND("debris/bustmetal1.wav"); + PRECACHE_SOUND("debris/bustmetal2.wav"); + break; + case matCinderBlock: + pGibName = "models/cindergibs.mdl"; + + PRECACHE_SOUND("debris/bustconcrete1.wav"); + PRECACHE_SOUND("debris/bustconcrete2.wav"); + break; + case matRocks: + pGibName = "models/rockgibs.mdl"; + + PRECACHE_SOUND("debris/bustconcrete1.wav"); + PRECACHE_SOUND("debris/bustconcrete2.wav"); + break; + case matCeilingTile: + pGibName = "models/ceilinggibs.mdl"; + + PRECACHE_SOUND ("debris/bustceiling.wav"); + break; + } + MaterialSoundPrecache( m_Material ); + if ( m_iszGibModel ) + pGibName = STRING(m_iszGibModel); + + m_idShard = PRECACHE_MODEL( (char *)pGibName ); + PRECACHE_MODEL( (char *)STRING(pev->model) ); } void CProp::DamageSound( void ) { - int pitch; - float fvol; - char *rgpsz[6]; - int i; - int material = m_Material; + int pitch; + float fvol; + char *rgpsz[6]; + int i; + int material = m_Material; // if (RANDOM_LONG(0,1)) // return; - if (RANDOM_LONG(0,2)) - pitch = PITCH_NORM; - else - pitch = 95 + RANDOM_LONG(0,34); - - fvol = RANDOM_FLOAT(0.75, 1.0); - - if (material == matComputer && RANDOM_LONG(0,1)) - material = matMetal; - - switch (material) - { - case matComputer: - case matGlass: - case matUnbreakableGlass: - rgpsz[0] = "debris/glass1.wav"; - rgpsz[1] = "debris/glass2.wav"; - rgpsz[2] = "debris/glass3.wav"; - i = 3; - break; - - case matWood: - rgpsz[0] = "debris/wood1.wav"; - rgpsz[1] = "debris/wood2.wav"; - rgpsz[2] = "debris/wood3.wav"; - i = 3; - break; - - case matMetal: - rgpsz[0] = "debris/metal1.wav"; - rgpsz[1] = "debris/metal3.wav"; - rgpsz[2] = "debris/metal2.wav"; - i = 2; - break; - - case matFlesh: - rgpsz[0] = "debris/flesh1.wav"; - rgpsz[1] = "debris/flesh2.wav"; - rgpsz[2] = "debris/flesh3.wav"; - rgpsz[3] = "debris/flesh5.wav"; - rgpsz[4] = "debris/flesh6.wav"; - rgpsz[5] = "debris/flesh7.wav"; - i = 6; - break; - - case matRocks: - case matCinderBlock: - rgpsz[0] = "debris/concrete1.wav"; - rgpsz[1] = "debris/concrete2.wav"; - rgpsz[2] = "debris/concrete3.wav"; - i = 3; - break; - - case matCeilingTile: - // UNDONE: no ceiling tile shard sound yet - i = 0; - break; - } - - if (i) - EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, rgpsz[RANDOM_LONG(0,i-1)], fvol, ATTN_NORM, 0, pitch); + if (RANDOM_LONG(0,2)) + pitch = PITCH_NORM; + else + pitch = 95 + RANDOM_LONG(0,34); + + fvol = RANDOM_FLOAT(0.75, 1.0); + + if (material == matComputer && RANDOM_LONG(0,1)) + material = matMetal; + + switch (material) + { + case matComputer: + case matGlass: + case matUnbreakableGlass: + rgpsz[0] = "debris/glass1.wav"; + rgpsz[1] = "debris/glass2.wav"; + rgpsz[2] = "debris/glass3.wav"; + i = 3; + break; + + case matWood: + rgpsz[0] = "debris/wood1.wav"; + rgpsz[1] = "debris/wood2.wav"; + rgpsz[2] = "debris/wood3.wav"; + i = 3; + break; + + case matMetal: + rgpsz[0] = "debris/metal1.wav"; + rgpsz[1] = "debris/metal3.wav"; + rgpsz[2] = "debris/metal2.wav"; + i = 2; + break; + + case matFlesh: + rgpsz[0] = "debris/flesh1.wav"; + rgpsz[1] = "debris/flesh2.wav"; + rgpsz[2] = "debris/flesh3.wav"; + rgpsz[3] = "debris/flesh5.wav"; + rgpsz[4] = "debris/flesh6.wav"; + rgpsz[5] = "debris/flesh7.wav"; + i = 6; + break; + + case matRocks: + case matCinderBlock: + rgpsz[0] = "debris/concrete1.wav"; + rgpsz[1] = "debris/concrete2.wav"; + rgpsz[2] = "debris/concrete3.wav"; + i = 3; + break; + + case matCeilingTile: + // UNDONE: no ceiling tile shard sound yet + i = 0; + break; + } + + if (i) + EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, rgpsz[RANDOM_LONG(0,i-1)], fvol, ATTN_NORM, 0, pitch); } void CProp::Die( void ) { - Vector vecSpot;// shard origin - Vector vecVelocity;// shard velocity - CBaseEntity *pEntity = NULL; - char cFlag = 0; - int pitch; - float fvol; - - pitch = 95 + RANDOM_LONG(0,29); - - if (pitch > 97 && pitch < 103) - pitch = 100; - - // The more negative pev->health, the louder - // the sound should be. - - fvol = RANDOM_FLOAT(0.85, 1.0) + (fabs(pev->health) / 100.0); - - if (fvol > 1.0) - fvol = 1.0; - - - switch (m_Material) - { - case matGlass: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_GLASS; - break; - - case matWood: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_WOOD; - break; - - case matComputer: - case matMetal: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_METAL; - break; - - case matFlesh: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_FLESH; - break; - - case matRocks: - case matCinderBlock: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_CONCRETE; - break; - - case matCeilingTile: - EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustceiling.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - - - if (m_Explosion == expDirected) - vecVelocity = g_vecAttackDir * 200; - else - { - vecVelocity.x = 0; - vecVelocity.y = 0; - vecVelocity.z = 0; - } - - vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot ); - WRITE_BYTE( TE_BREAKMODEL); - - // position - WRITE_COORD( vecSpot.x ); - WRITE_COORD( vecSpot.y ); - WRITE_COORD( vecSpot.z ); - - // size - WRITE_COORD( pev->size.x); - WRITE_COORD( pev->size.y); - WRITE_COORD( pev->size.z); - - // velocity - WRITE_COORD( vecVelocity.x ); - WRITE_COORD( vecVelocity.y ); - WRITE_COORD( vecVelocity.z ); - - // randomization - WRITE_BYTE( 10 ); - - // Model - WRITE_SHORT( m_idShard ); //model id# - - // # of shards - WRITE_BYTE( 0 ); // let client decide - - // duration - WRITE_BYTE( 25 );// 2.5 seconds - - // flags - WRITE_BYTE( cFlag ); - MESSAGE_END(); - - float size = pev->size.x; - if ( size < pev->size.y ) - size = pev->size.y; - if ( size < pev->size.z ) - size = pev->size.z; - - // !!! HACK This should work! - // Build a box above the entity that looks like an 8 pixel high sheet - Vector mins = pev->absmin; - Vector maxs = pev->absmax; - mins.z = pev->absmax.z; - maxs.z += 8; - - // BUGBUG -- can only find 256 entities on a breakable -- should be enough - CBaseEntity *pList[256]; - int count = UTIL_EntitiesInBox( pList, 256, mins, maxs, FL_ONGROUND ); - if ( count ) - { - for ( int i = 0; i < count; i++ ) - { - ClearBits( pList[i]->pev->flags, FL_ONGROUND ); - pList[i]->pev->groundentity = NULL; - } - } - - // Don't fire something that could fire myself - pev->targetname = 0; - - pev->solid = SOLID_NOT; - // Fire targets on break - SUB_UseTargets( NULL, USE_TOGGLE, 0 ); - - if ( Explodable() ) - { - ExplosionCreate( pev->origin, pev->angles, m_attacker, ExplosionMagnitude(), TRUE ); - } + Vector vecSpot;// shard origin + Vector vecVelocity;// shard velocity + CBaseEntity *pEntity = NULL; + char cFlag = 0; + int pitch; + float fvol; + + pitch = 95 + RANDOM_LONG(0,29); + + if (pitch > 97 && pitch < 103) + pitch = 100; + + // The more negative pev->health, the louder + // the sound should be. + + fvol = RANDOM_FLOAT(0.85, 1.0) + (fabs(pev->health) / 100.0); + + if (fvol > 1.0) + fvol = 1.0; + + + switch (m_Material) + { + case matGlass: + switch ( RANDOM_LONG(0,1) ) + { + case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass1.wav", fvol, ATTN_NORM, 0, pitch); + break; + case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass2.wav", fvol, ATTN_NORM, 0, pitch); + break; + } + cFlag = BREAK_GLASS; + break; + + case matWood: + switch ( RANDOM_LONG(0,1) ) + { + case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate1.wav", fvol, ATTN_NORM, 0, pitch); + break; + case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate2.wav", fvol, ATTN_NORM, 0, pitch); + break; + } + cFlag = BREAK_WOOD; + break; + + case matComputer: + case matMetal: + switch ( RANDOM_LONG(0,1) ) + { + case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal1.wav", fvol, ATTN_NORM, 0, pitch); + break; + case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal2.wav", fvol, ATTN_NORM, 0, pitch); + break; + } + cFlag = BREAK_METAL; + break; + + case matFlesh: + switch ( RANDOM_LONG(0,1) ) + { + case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh1.wav", fvol, ATTN_NORM, 0, pitch); + break; + case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh2.wav", fvol, ATTN_NORM, 0, pitch); + break; + } + cFlag = BREAK_FLESH; + break; + + case matRocks: + case matCinderBlock: + switch ( RANDOM_LONG(0,1) ) + { + case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete1.wav", fvol, ATTN_NORM, 0, pitch); + break; + case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete2.wav", fvol, ATTN_NORM, 0, pitch); + break; + } + cFlag = BREAK_CONCRETE; + break; + + case matCeilingTile: + EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustceiling.wav", fvol, ATTN_NORM, 0, pitch); + break; + } + + + if (m_Explosion == expDirected) + vecVelocity = g_vecAttackDir * 200; + else + { + vecVelocity.x = 0; + vecVelocity.y = 0; + vecVelocity.z = 0; + } + + vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; + MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot ); + WRITE_BYTE( TE_BREAKMODEL); + + // position + WRITE_COORD( vecSpot.x ); + WRITE_COORD( vecSpot.y ); + WRITE_COORD( vecSpot.z ); + + // size + WRITE_COORD( pev->size.x); + WRITE_COORD( pev->size.y); + WRITE_COORD( pev->size.z); + + // velocity + WRITE_COORD( vecVelocity.x ); + WRITE_COORD( vecVelocity.y ); + WRITE_COORD( vecVelocity.z ); + + // randomization + WRITE_BYTE( 10 ); + + // Model + WRITE_SHORT( m_idShard ); //model id# + + // # of shards + WRITE_BYTE( 0 ); // let client decide + + // duration + WRITE_BYTE( 25 );// 2.5 seconds + + // flags + WRITE_BYTE( cFlag ); + MESSAGE_END(); + + float size = pev->size.x; + if ( size < pev->size.y ) + size = pev->size.y; + if ( size < pev->size.z ) + size = pev->size.z; + + // !!! HACK This should work! + // Build a box above the entity that looks like an 8 pixel high sheet + Vector mins = pev->absmin; + Vector maxs = pev->absmax; + mins.z = pev->absmax.z; + maxs.z += 8; + + // BUGBUG -- can only find 256 entities on a breakable -- should be enough + CBaseEntity *pList[256]; + int count = UTIL_EntitiesInBox( pList, 256, mins, maxs, FL_ONGROUND ); + if ( count ) + { + for ( int i = 0; i < count; i++ ) + { + ClearBits( pList[i]->pev->flags, FL_ONGROUND ); + pList[i]->pev->groundentity = NULL; + } + } + + // Don't fire something that could fire myself + pev->targetname = 0; + + pev->solid = SOLID_NOT; + // Fire targets on break + SUB_UseTargets( NULL, USE_TOGGLE, 0 ); + + if ( Explodable() ) + { + ExplosionCreate( pev->origin, pev->angles, m_attacker, ExplosionMagnitude(), TRUE ); + } } void CProp::Killed(entvars_t *pevAttacker, int iGib) { - pev->takedamage = DAMAGE_NO; - pev->deadflag = DEAD_DEAD; - pev->solid = SOLID_NOT; - pev->effects |= EF_NODRAW; - pev->nextthink = gpGlobals->time + m_flRespawnTime; - SetThink( &CProp::RespawnThink ); - ResetTouch( ); - ResetUse( ); + pev->takedamage = DAMAGE_NO; + pev->deadflag = DEAD_DEAD; + pev->solid = SOLID_NOT; + pev->effects |= EF_NODRAW; + pev->nextthink = gpGlobals->time + m_flRespawnTime; + SetThink( &CProp::RespawnThink ); + ResetTouch( ); + ResetUse( ); } void CProp::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) { - if (m_owner2 != pActivator->edict()) - { - if (pev->velocity.Length() < 100 && pActivator->IsPlayer()) - { - m_owner2 = m_attacker = pActivator->edict(); - } - else - return; - } - if( pActivator->IsPlayer() ) - { - m_pHolstered = (CBasePlayer *) pActivator; - if( m_pHolstered ) - { - - if ( m_pHolstered->m_pActiveItem ) - { - CBasePlayerWeapon *weapon = (CBasePlayerWeapon *) m_pHolstered->m_pActiveItem->GetWeaponPtr(); - - - //m_Holstered->m_pActiveItem->Holster(); // strange bug here. ValveWHY? - - // HACK: prevent attack - if( weapon ) - { - weapon->m_flNextPrimaryAttack += 0.1; - weapon->m_flNextSecondaryAttack += 0.1; - } - m_pHolstered->m_iHideHUD |= HIDEHUD_WEAPONS; - m_pHolstered->pev->weaponmodel = 0; - m_pHolstered->pev->viewmodel = 0; - } - SetThink( &CProp::DeployThink ); - pev->nextthink = gpGlobals->time + 0.2; - } - } - Vector target = pActivator->pev->origin + UTIL_GetAimVector(m_owner2, 1000) * 50; - target.z = target.z + 32; - pev->velocity = (target - VecBModelOrigin(pev)) * 10; - Vector atarget = UTIL_VecToAngles(UTIL_GetAimVector(m_owner2, 1000)); - pev->angles.x = UTIL_AngleMod(pev->angles.x); - pev->angles.y = UTIL_AngleMod(pev->angles.y); - pev->angles.z = UTIL_AngleMod(pev->angles.z); - atarget.x = UTIL_AngleMod(atarget.x); - atarget.y = UTIL_AngleMod(atarget.y); - atarget.z = UTIL_AngleMod(atarget.z); - pev->avelocity.x = UTIL_AngleDiff(atarget.x, pev->angles.x) * 10; - pev->avelocity.y = UTIL_AngleDiff(atarget.y, pev->angles.y) * 10; - pev->avelocity.z = UTIL_AngleDiff(atarget.z, pev->angles.z) * 10; - //pev->angles.z += (0 - pev->angles.z) * 0.06; - if ((pActivator->pev->button & (IN_ATTACK))) - { - pev->velocity = UTIL_GetAimVector(m_owner2, 1000) * 1000; - pev->avelocity.y = pev->avelocity.y*1.5 + RANDOM_FLOAT(100, -100); - pev->avelocity.x = pev->avelocity.x*1.5 + RANDOM_FLOAT(100, -100); - //pev->avelocity.z = pev->avelocity.z*0.5 + RANDOM_FLOAT ( 100, -100 ); - } - if ((pActivator->pev->button & (IN_ATTACK2))) - { - //m_Horizontal = false; - //pev->angles.z = 0; - } - // m_Horizontal = (fabs(UTIL_AngleDiff(pev->angles.z, 90)) < 20) || ( sin(pev->angles.x/180*M_PI) > 0.1); - // CheckRotate(); - //ALERT( at_console, "Prop use!\n"); + if (m_owner2 != pActivator->edict()) + { + if (pev->velocity.Length() < 100 && pActivator->IsPlayer()) + { + m_owner2 = m_attacker = pActivator->edict(); + } + else + return; + } + if( pActivator->IsPlayer() ) + { + m_pHolstered = (CBasePlayer *) pActivator; + if( m_pHolstered ) + { + + if ( m_pHolstered->m_pActiveItem ) + { + CBasePlayerWeapon *weapon = (CBasePlayerWeapon *) m_pHolstered->m_pActiveItem->GetWeaponPtr(); + + + //m_Holstered->m_pActiveItem->Holster(); // strange bug here. ValveWHY? + + // HACK: prevent attack + if( weapon ) + { + weapon->m_flNextPrimaryAttack += 0.1; + weapon->m_flNextSecondaryAttack += 0.1; + } + m_pHolstered->m_iHideHUD |= HIDEHUD_WEAPONS; + m_pHolstered->pev->weaponmodel = 0; + m_pHolstered->pev->viewmodel = 0; + } + SetThink( &CProp::DeployThink ); + pev->nextthink = gpGlobals->time + 0.2; + } + } + Vector target = pActivator->pev->origin + UTIL_GetAimVector(m_owner2, 1000) * 50; + target.z = target.z + 32; + pev->velocity = (target - VecBModelOrigin(pev)) * 10; + Vector atarget = UTIL_VecToAngles(UTIL_GetAimVector(m_owner2, 1000)); + pev->angles.x = UTIL_AngleMod(pev->angles.x); + pev->angles.y = UTIL_AngleMod(pev->angles.y); + pev->angles.z = UTIL_AngleMod(pev->angles.z); + atarget.x = UTIL_AngleMod(atarget.x); + atarget.y = UTIL_AngleMod(atarget.y); + atarget.z = UTIL_AngleMod(atarget.z); + pev->avelocity.x = UTIL_AngleDiff(atarget.x, pev->angles.x) * 10; + pev->avelocity.y = UTIL_AngleDiff(atarget.y, pev->angles.y) * 10; + pev->avelocity.z = UTIL_AngleDiff(atarget.z, pev->angles.z) * 10; + //pev->angles.z += (0 - pev->angles.z) * 0.06; + if ((pActivator->pev->button & (IN_ATTACK))) + { + pev->velocity = UTIL_GetAimVector(m_owner2, 1000) * 1000; + pev->avelocity.y = pev->avelocity.y*1.5 + RANDOM_FLOAT(100, -100); + pev->avelocity.x = pev->avelocity.x*1.5 + RANDOM_FLOAT(100, -100); + //pev->avelocity.z = pev->avelocity.z*0.5 + RANDOM_FLOAT ( 100, -100 ); + } + if ((pActivator->pev->button & (IN_ATTACK2))) + { + //m_Horizontal = false; + //pev->angles.z = 0; + } + // m_Horizontal = (fabs(UTIL_AngleDiff(pev->angles.z, 90)) < 20) || ( sin(pev->angles.x/180*M_PI) > 0.1); + // CheckRotate(); + //ALERT( at_console, "Prop use!\n"); } void CProp::Force(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) { - if (m_owner2 != pActivator->edict()) - { - if (pev->velocity.Length() < 100 && pActivator->IsPlayer()) - m_attacker = pActivator->edict(); - else - return; - } - - if ((pActivator->pev->button & (IN_ATTACK))) - { - pev->velocity = UTIL_GetAimVector(m_owner2, 3000) * 1000; - pev->avelocity.y = pev->avelocity.y*1.5 + RANDOM_FLOAT(100, -100); - pev->avelocity.x = pev->avelocity.x*1.5 + RANDOM_FLOAT(100, -100); - //pev->avelocity.z = pev->avelocity.z*0.5 + RANDOM_FLOAT ( 100, -100 ); - } - if ((pActivator->pev->button & (IN_ATTACK2))) - { - //m_Horizontal = false; - //pev->angles.z = 0; - } - - pev->nextthink = gpGlobals->time + m_flRespawnTime; - SetThink( &CProp::RespawnThink); + if (m_owner2 != pActivator->edict()) + { + if (pev->velocity.Length() < 100 && pActivator->IsPlayer()) + m_attacker = pActivator->edict(); + else + return; + } + + if ((pActivator->pev->button & (IN_ATTACK))) + { + pev->velocity = UTIL_GetAimVector(m_owner2, 3000) * 1000; + pev->avelocity.y = pev->avelocity.y*1.5 + RANDOM_FLOAT(100, -100); + pev->avelocity.x = pev->avelocity.x*1.5 + RANDOM_FLOAT(100, -100); + //pev->avelocity.z = pev->avelocity.z*0.5 + RANDOM_FLOAT ( 100, -100 ); + } + if ((pActivator->pev->button & (IN_ATTACK2))) + { + //m_Horizontal = false; + //pev->angles.z = 0; + } + + pev->nextthink = gpGlobals->time + m_flRespawnTime; + SetThink( &CProp::RespawnThink); } void CProp::CheckRotate() { - if( m_shape != SHAPE_CYL_H && m_shape != SHAPE_CYL_V ) - { - UTIL_SetSize(pev, minsH, maxsH); - return; - } - if( (fabs(UTIL_AngleDiff(pev->angles.z, 90)) < 20) || - (fabs(sin(pev->angles.x / 180 * M_PI)) > 0.3) ) - m_shape = SHAPE_CYL_H; - else - m_shape = SHAPE_CYL_V; - - if (m_oldshape != m_shape) - { - - if (m_shape == SHAPE_CYL_H) - { - pev->angles.y += 90; - - ALERT(at_console, "setHorizontal: %f %f %f\n", pev->angles.x, pev->angles.y, pev->angles.z); - - UTIL_SetSize(pev, minsH, maxsH); - } - else if (m_shape == SHAPE_CYL_V) - { - Vector mins = pev->absmin; - Vector maxs = pev->absmax; - - mins.z = pev->absmax.z; - maxs.z += 10; - - // BUGBUG -- can only find 256 entities on a prop -- should be enough - CBaseEntity *pList[256]; - int count = UTIL_EntitiesInBox( pList, 256, mins, maxs, FL_ONGROUND ); - if ( count ) - { - for ( int i = 0; i < count; i++ ) - { - pList[i]->pev->origin.z += 10; - } - } - pev->origin.z += 10; - //pev->angles.y -= 90; - UTIL_SetSize(pev, minsV, maxsV); - } - //DROP_TO_FLOOR(edict()); - //pev->origin.z += 0.5; - m_oldshape = m_shape; - } + if( m_shape != SHAPE_CYL_H && m_shape != SHAPE_CYL_V ) + { + UTIL_SetSize(pev, minsH, maxsH); + return; + } + if( (fabs(UTIL_AngleDiff(pev->angles.z, 90)) < 20) || + (fabs(sin(pev->angles.x / 180 * M_PI)) > 0.3) ) + m_shape = SHAPE_CYL_H; + else + m_shape = SHAPE_CYL_V; + + if (m_oldshape != m_shape) + { + + if (m_shape == SHAPE_CYL_H) + { + pev->angles.y += 90; + + ALERT(at_console, "setH: %f %f %f\n", pev->angles.x, pev->angles.y, pev->angles.z); + + UTIL_SetSize(pev, minsH, maxsH); + } + else if (m_shape == SHAPE_CYL_V) + { + Vector mins = pev->absmin; + Vector maxs = pev->absmax; + + mins.z = pev->absmax.z; + maxs.z += 10; + ALERT(at_console, "setV: %f %f %f\n", pev->angles.x, pev->angles.y, pev->angles.z); + + // BUGBUG -- can only find 256 entities on a prop -- should be enough + CBaseEntity *pList[256]; + int count = UTIL_EntitiesInBox( pList, 256, mins, maxs, FL_ONGROUND ); + if ( count ) + { + for ( int i = 0; i < count; i++ ) + { + pList[i]->pev->origin.z += 10; + } + } + pev->origin.z += 10; + //pev->angles.y -= 90; + UTIL_SetSize(pev, minsV, maxsV); + } + //DROP_TO_FLOOR(edict()); + //pev->origin.z += 0.5; + m_oldshape = m_shape; + } } void CProp::DeployThink( void ) { - if( m_pHolstered ) - { - if( m_pHolstered->m_pActiveItem ) - { - m_pHolstered->m_pActiveItem->Deploy(); - CBasePlayerWeapon *weapon = (CBasePlayerWeapon *) m_pHolstered->m_pActiveItem->GetWeaponPtr(); - if( weapon ) - { - weapon->m_flNextPrimaryAttack = 0; - weapon->m_flNextSecondaryAttack = 0; - } - } - m_pHolstered ->m_iHideHUD &= ~HIDEHUD_WEAPONS; - m_pHolstered = NULL; - } - if( m_pfnThink == &CProp::DeployThink ) - { - pev->nextthink = gpGlobals->time + m_flRespawnTime; - SetThink( &CProp::RespawnThink ); - } + if( m_pHolstered ) + { + if( m_pHolstered->m_pActiveItem ) + { + m_pHolstered->m_pActiveItem->Deploy(); + CBasePlayerWeapon *weapon = (CBasePlayerWeapon *) m_pHolstered->m_pActiveItem->GetWeaponPtr(); + if( weapon ) + { + weapon->m_flNextPrimaryAttack = 0; + weapon->m_flNextSecondaryAttack = 0; + } + } + m_pHolstered ->m_iHideHUD &= ~HIDEHUD_WEAPONS; + m_pHolstered = NULL; + } + if( m_pfnThink == &CProp::DeployThink ) + { + pev->nextthink = gpGlobals->time + m_flRespawnTime; + SetThink( &CProp::RespawnThink ); + } } void CProp::BounceTouch(CBaseEntity *pOther) { - //ALERT( at_console, "BounceTouch: %f %f %f\n", pev->angles.x, pev->angles.y, pev->angles.z ); - // only do damage if we're moving fairly fast - DeployThink(); - - if ( m_flNextAttack < gpGlobals->time && pev->velocity.Length() > 300) - { - entvars_t *pevOwner = VARS(m_attacker); - if (pevOwner) - { - float dmg = 50 + pev->velocity.Length() / 40; - if (pOther->edict() == m_owner2) - { - dmg = 5; - if (pOther->pev->button & (IN_USE)) - { - dmg = 1; - } - } - TraceResult tr = UTIL_GetGlobalTrace(); - ClearMultiDamage(); - pOther->TraceAttack(pevOwner, dmg, gpGlobals->v_forward, &tr, DMG_CLUB); - ApplyMultiDamage(pev, pevOwner); - } - m_flNextAttack = gpGlobals->time + 1.0; // debounce - } - if( (pev->spawnflags & SF_PROP_BREAKABLE) && (pev->velocity.Length() > 700) ) - { - Killed( VARS(m_attacker), GIB_NORMAL ); - Die(); - } - - pev->velocity = pev->velocity + pOther->pev->velocity; - float dp = cos(M_PI / 180 * UTIL_AngleDiff(UTIL_VecToAngles(pev->velocity).y, pev->angles.y)); - if (pev->flags & FL_ONGROUND || fabs(pev->velocity.z) < 40) - { - CheckRotate(); - if (m_shape == SHAPE_CYL_H) - { - - pev->velocity.x *= fabs(dp) * 0.8 + 0.2; - pev->velocity.y *= fabs(dp) * 0.8 + 0.2; - pev->velocity.z -= 20; - pev->avelocity.x = -dp*pev->velocity.Length()* 1.5; - pev->avelocity.y = 0; - pev->avelocity.z = 0; - pev->angles.z += UTIL_AngleDiff(90, pev->angles.z) * 0.7; - //AngleThink(); - } - else if (m_shape == SHAPE_CYL_V) - { - // pev->angles.z *= 0.3; - //pev->angles.x *= 0.3; - //AngleThink(); - //CheckRotate(); - pev->velocity.z *= m_flFloorFriction; - pev->velocity.x *= m_flFloorFriction; - pev->velocity.y *= m_flFloorFriction; - pev->velocity.z -= 10; - pev->avelocity.y = pev->avelocity.y*0.4 + RANDOM_FLOAT(30, -30); - } - else if( m_shape == SHAPE_SPHERE ) - { - pev->velocity.z -= 20; - pev->avelocity.x = -cos(M_PI / 180 * UTIL_AngleDiff(UTIL_VecToAngles(pev->velocity).y, pev->angles.y))*pev->velocity.Length()* 1.5; - pev->avelocity.y = -sin(M_PI / 180 * UTIL_AngleDiff(UTIL_VecToAngles(pev->velocity).y, pev->angles.y))*pev->velocity.Length()* 1.5;; - pev->avelocity.z = 0; - } - else if( m_shape == SHAPE_BOX || m_shape == SHAPE_GENERIC ) - { - pev->velocity.z *= m_flFloorFriction; - pev->velocity.x *= m_flFloorFriction; - pev->velocity.y *= m_flFloorFriction; - pev->velocity.z -= 10; - } - - } - else - { - { - pev->velocity.z *= 0.3; - pev->velocity.y *= m_flCollideFriction; - pev->velocity.x *= m_flCollideFriction; - if( m_shape != SHAPE_SPHERE ) - { - pev->avelocity.y = pev->avelocity.y*0.4 + RANDOM_FLOAT(100, -100); - pev->avelocity.x = pev->avelocity.x*0.5 + RANDOM_FLOAT(100, -100); - } - } - //pev->avelocity.z = pev->avelocity.z*0.5 + RANDOM_FLOAT ( 1, -1 ); - BounceSound(); - } - pev->framerate = pev->velocity.Length() / 200.0; - if (pev->framerate > 1.0) - pev->framerate = 1; - else if (pev->framerate < 0.2) - { - CheckRotate(); - AngleThink(); - if (pev->angles.z == 0 || pev->angles.z == 90) - pev->framerate = 0; - else - pev->framerate = 0.2; - } + //ALERT( at_console, "BounceTouch: %f %f %f\n", pev->angles.x, pev->angles.y, pev->angles.z ); + // only do damage if we're moving fairly fast + DeployThink(); + + if ( m_flNextAttack < gpGlobals->time && pev->velocity.Length() > 300) + { + entvars_t *pevOwner = VARS(m_attacker); + if (pevOwner) + { + float dmg = 50 + pev->velocity.Length() / 40; + if (pOther->edict() == m_owner2) + { + dmg = 5; + if (pOther->pev->button & (IN_USE)) + { + dmg = 1; + } + } + TraceResult tr = UTIL_GetGlobalTrace(); + ClearMultiDamage(); + pOther->TraceAttack(pevOwner, dmg, gpGlobals->v_forward, &tr, DMG_CLUB); + ApplyMultiDamage(pev, pevOwner); + } + m_flNextAttack = gpGlobals->time + 1.0; // debounce + } + if( (pev->spawnflags & SF_PROP_BREAKABLE) && (pev->velocity.Length() > 700) ) + { + Killed( VARS(m_attacker), GIB_NORMAL ); + Die(); + } + + pev->velocity = pev->velocity + pOther->pev->velocity; + float dp = cos(M_PI / 180 * UTIL_AngleDiff(UTIL_VecToAngles(pev->velocity).y, pev->angles.y)); + if (pev->flags & FL_ONGROUND || fabs(pev->velocity.z) < 40) + { + CheckRotate(); + if (m_shape == SHAPE_CYL_H) + { + + pev->velocity.x *= fabs(dp) * 0.8 + 0.2; + pev->velocity.y *= fabs(dp) * 0.8 + 0.2; + pev->velocity.z -= 20; + pev->avelocity.x = -dp*pev->velocity.Length()* 1.5; + pev->avelocity.y = 0; + pev->avelocity.z = 0; + pev->angles.z += UTIL_AngleDiff(90, pev->angles.z) * 0.7; + //AngleThink(); + } + else if (m_shape == SHAPE_CYL_V) + { + // pev->angles.z *= 0.3; + //pev->angles.x *= 0.3; + //AngleThink(); + //CheckRotate(); + pev->velocity.z *= m_flFloorFriction; + pev->velocity.x *= m_flFloorFriction; + pev->velocity.y *= m_flFloorFriction; + pev->velocity.z -= 10; + pev->avelocity.y = pev->avelocity.y*0.4 + RANDOM_FLOAT(30, -30); + } + else if( m_shape == SHAPE_SPHERE ) + { + pev->velocity.z -= 20; + pev->avelocity.x = -cos(M_PI / 180 * UTIL_AngleDiff(UTIL_VecToAngles(pev->velocity).y, pev->angles.y))*pev->velocity.Length()* 1.5; + pev->avelocity.y = -sin(M_PI / 180 * UTIL_AngleDiff(UTIL_VecToAngles(pev->velocity).y, pev->angles.y))*pev->velocity.Length()* 1.5;; + pev->avelocity.z = 0; + } + else if( m_shape == SHAPE_BOX || m_shape == SHAPE_GENERIC ) + { + pev->velocity.z *= m_flFloorFriction; + pev->velocity.x *= m_flFloorFriction; + pev->velocity.y *= m_flFloorFriction; + pev->velocity.z -= 10; + } + + } + else + { + { + pev->velocity.z *= 0.3; + pev->velocity.y *= m_flCollideFriction; + pev->velocity.x *= m_flCollideFriction; + if( m_shape != SHAPE_SPHERE ) + { + pev->avelocity.y = pev->avelocity.y*0.4 + RANDOM_FLOAT(100, -100); + pev->avelocity.x = pev->avelocity.x*0.5 + RANDOM_FLOAT(100, -100); + } + } + //pev->avelocity.z = pev->avelocity.z*0.5 + RANDOM_FLOAT ( 1, -1 ); + BounceSound(); + } + pev->framerate = pev->velocity.Length() / 200.0; + if (pev->framerate > 1.0) + pev->framerate = 1; + else if (pev->framerate < 0.2) + { + CheckRotate(); + AngleThink(); + if (pev->angles.z == 0 || pev->angles.z == 90) + pev->framerate = 0; + else + pev->framerate = 0.2; + } } void CProp::BounceSound(void) { - switch (RANDOM_LONG(0, 2)) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit1.wav", 0.25, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit2.wav", 0.25, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit3.wav", 0.25, ATTN_NORM); break; - } + switch (RANDOM_LONG(0, 2)) + { + case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit1.wav", 0.25, ATTN_NORM); break; + case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit2.wav", 0.25, ATTN_NORM); break; + case 2: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit3.wav", 0.25, ATTN_NORM); break; + } } void CProp::Spawn(void) { - Precache(); - - if( !pev->model ) - pev->model = MAKE_STRING( "models/xash/barrel_brown.mdl" ); - - if( minsH == g_vecZero ) - { - // default barrel parameters - minsV = Vector(-10, -10, -17); - maxsV = Vector(10, 10, 18); - minsH = Vector(-10, -10, -10); - maxsH = Vector(10, 10, 13); - } - m_flCollideFriction = 0.7; - m_flFloorFriction = 0.5; - spawnOrigin = pev->origin; - spawnAngles = pev->angles; - m_flSpawnHealth = pev->health; - if( !m_flRespawnTime ) - m_flRespawnTime = 20; - pev->dmg = 100; - PropRespawn(); + Precache(); + + if( minsH == g_vecZero ) + { + // default barrel parameters + minsV = Vector(-10, -10, -17); + maxsV = Vector(10, 10, 18); + minsH = Vector(-10, -10, -10); + maxsH = Vector(10, 10, 13); + } + m_flCollideFriction = 0.7; + m_flFloorFriction = 0.5; + spawnOrigin = pev->origin; + spawnAngles = pev->angles; + m_flSpawnHealth = pev->health; + if( m_flSpawnHealth <= 0 ) + m_flSpawnHealth = 30; + if( !m_flRespawnTime ) + m_flRespawnTime = 20; + pev->dmg = 100; + PropRespawn(); } void CProp::PropRespawn() { - pev->movetype = MOVETYPE_BOUNCE; - pev->solid = SOLID_SLIDEBOX; - pev->angles = spawnAngles; - pev->takedamage = DAMAGE_YES; - pev->velocity = pev->avelocity = g_vecZero; - SET_MODEL( ENT(pev), STRING(pev->model) ); - UTIL_SetOrigin( pev, spawnOrigin ); - m_oldshape = (PropShape)-1; - CheckRotate(); - pev->health = m_flSpawnHealth; - SetTouch( &CProp::BounceTouch); - SetUse( &CProp::Use); - pev->effects &= ~EF_NODRAW; - pev->framerate = 1.0f; + pev->movetype = MOVETYPE_BOUNCE; + pev->solid = SOLID_SLIDEBOX; + pev->angles = spawnAngles; + pev->takedamage = DAMAGE_YES; + pev->velocity = pev->avelocity = g_vecZero; + SET_MODEL( ENT(pev), STRING(pev->model) ); + UTIL_SetOrigin( pev, spawnOrigin ); + + m_oldshape = (PropShape)-1; + CheckRotate(); + pev->health = m_flSpawnHealth; + SetTouch( &CProp::BounceTouch); + SetUse( &CProp::Use); + pev->effects &= ~EF_NODRAW; + pev->framerate = 1.0f; + UTIL_SetOrigin( pev, spawnOrigin ); } void CProp::RespawnThink() { - if( !(pev->spawnflags & SF_PROP_RESPAWN)) - return; - PropRespawn(); + if( !(pev->spawnflags & SF_PROP_RESPAWN)) + return; + PropRespawn(); } void CProp::AngleThink() { - pev->nextthink = gpGlobals->time + m_flRespawnTime; - SetThink( &CProp::RespawnThink); - if (!(pev->flags & FL_ONGROUND || fabs(pev->velocity.z) < 40)) - { - m_owner2 = m_attacker = 0; - return; - } - if (m_shape == SHAPE_CYL_H) - { - pev->angles.z += UTIL_AngleDiff(90, pev->angles.z) * 0.7; - if (fabs(UTIL_AngleDiff(90, pev->angles.z)) > 0.1) - { - SetThink( &CProp::AngleThink); - pev->nextthink = gpGlobals->time + 0.1; - } - //ALERT( at_console, "AngleThink: %f %f %f\n", pev->angles.x, pev->angles.y, pev->angles.z ); - pev->avelocity.y = pev->avelocity.z = 0; - } - else if (m_shape == SHAPE_CYL_V) - { - if (fabs(UTIL_AngleDiff(90, pev->angles.z)) > 0.1) - { - SetThink( &CProp::AngleThink); - pev->nextthink = gpGlobals->time + 0.1; - } - pev->angles.z += UTIL_AngleDiff(0, pev->angles.z) * 0.7; - //pev->angles.x += UTIL_AngleDiff( 0, pev->angles.x ) * 0.3; - pev->avelocity.x = pev->avelocity.y = pev->avelocity.z = 0; - } - else if (m_shape == SHAPE_BOX) - { - Vector iangles; - iangles.x = round( pev->angles.x / 90 ) * 90; - iangles.y = round( pev->angles.y / 90 ) * 90; - iangles.z = round( pev->angles.z / 90 ) * 90; - if (fabs(UTIL_AngleDiff(iangles.x, pev->angles.x)) > 0.1 || - //fabs(UTIL_AngleDiff(iangles.y, pev->angles.y)) > 0.1 || - fabs(UTIL_AngleDiff(iangles.z, pev->angles.z)) > 0.1) - { - SetThink( &CProp::AngleThink); - pev->nextthink = gpGlobals->time + 0.1; - } - pev->angles.x += UTIL_AngleDiff(iangles.x, pev->angles.x) * 0.6; - //pev->angles.y += UTIL_AngleDiff(iangles.y, pev->angles.y) * 0.6; - pev->angles.z += UTIL_AngleDiff(iangles.z, pev->angles.z) * 0.6; - - pev->avelocity.x = pev->avelocity.y = pev->avelocity.z = 0; - } - else if (m_shape == SHAPE_NOROTATE) - { - pev->avelocity.x = pev->avelocity.y = pev->avelocity.z = 0; - Vector iangles = spawnAngles; - if (fabs(UTIL_AngleDiff(iangles.x, pev->angles.x)) > 0.1 || - fabs(UTIL_AngleDiff(iangles.y, pev->angles.y)) > 0.1 || - fabs(UTIL_AngleDiff(iangles.z, pev->angles.z)) > 0.1) - { - SetThink( &CProp::AngleThink); - pev->nextthink = gpGlobals->time + 0.1; - } - pev->angles.x += UTIL_AngleDiff(iangles.x, pev->angles.x) * 0.6; - pev->angles.y += UTIL_AngleDiff(iangles.y, pev->angles.y) * 0.6; - pev->angles.z += UTIL_AngleDiff(iangles.z, pev->angles.z) * 0.6; - } - else if (m_shape == SHAPE_GENERIC) - { - float ianglex = 0, ianglez = 0, imaxanglediff=360.0f; - // if first number is zero, it is angle - // all other zeroes is array end - for( int i = 0; (i < 10) && ( (i == 0 ) || m_iaCustomAnglesX[i] ); i++) - { - float anglediff = fabs(UTIL_AngleDiff(pev->angles.x, m_iaCustomAnglesX[i])); - if( imaxanglediff > anglediff ) - { - ianglex = m_iaCustomAnglesX[i]; - imaxanglediff = anglediff; - } - } - imaxanglediff=360.0f; - for( int i = 0; (i < 10) && ( (i == 0 ) || m_iaCustomAnglesZ[i] ); i++) - { - float anglediff = fabs(UTIL_AngleDiff(pev->angles.z, m_iaCustomAnglesZ[i])); - if( imaxanglediff > anglediff ) - { - ianglez = m_iaCustomAnglesZ[i]; - imaxanglediff = anglediff; - } - } - if (fabs(UTIL_AngleDiff(ianglex, pev->angles.x)) > 0.1 || - fabs(UTIL_AngleDiff(ianglez, pev->angles.z)) > 0.1 ) - { - SetThink( &CProp::AngleThink); - pev->nextthink = gpGlobals->time + 0.1; - } - pev->angles.x += UTIL_AngleDiff(ianglex, pev->angles.x) * 0.6; - pev->angles.z += UTIL_AngleDiff(ianglez, pev->angles.z) * 0.6; - pev->avelocity.x = pev->avelocity.y = pev->avelocity.z = 0; - } - pev->angles.x = UTIL_AngleMod(pev->angles.x); - pev->angles.y = UTIL_AngleMod(pev->angles.y); - pev->angles.z = UTIL_AngleMod(pev->angles.z); + pev->nextthink = gpGlobals->time + m_flRespawnTime; + SetThink( &CProp::RespawnThink); + if (!(pev->flags & FL_ONGROUND || fabs(pev->velocity.z) < 40)) + { + m_owner2 = m_attacker = 0; + return; + } + if (m_shape == SHAPE_CYL_H) + { + pev->angles.z += UTIL_AngleDiff(90, pev->angles.z) * 0.7; + if (fabs(UTIL_AngleDiff(90, pev->angles.z)) > 0.1) + { + SetThink( &CProp::AngleThink); + pev->nextthink = gpGlobals->time + 0.1; + } + //ALERT( at_console, "AngleThink: %f %f %f\n", pev->angles.x, pev->angles.y, pev->angles.z ); + pev->avelocity.y = pev->avelocity.z = 0; + } + else if (m_shape == SHAPE_CYL_V) + { + if (fabs(UTIL_AngleDiff(90, pev->angles.z)) > 0.1) + { + SetThink( &CProp::AngleThink); + pev->nextthink = gpGlobals->time + 0.1; + } + pev->angles.z += UTIL_AngleDiff(0, pev->angles.z) * 0.7; + //pev->angles.x += UTIL_AngleDiff( 0, pev->angles.x ) * 0.3; + pev->avelocity.x = pev->avelocity.y = pev->avelocity.z = 0; + } + else if (m_shape == SHAPE_BOX) + { + Vector iangles; + iangles.x = round( pev->angles.x / 90 ) * 90; + iangles.y = round( pev->angles.y / 90 ) * 90; + iangles.z = round( pev->angles.z / 90 ) * 90; + if (fabs(UTIL_AngleDiff(iangles.x, pev->angles.x)) > 0.1 || + //fabs(UTIL_AngleDiff(iangles.y, pev->angles.y)) > 0.1 || + fabs(UTIL_AngleDiff(iangles.z, pev->angles.z)) > 0.1) + { + SetThink( &CProp::AngleThink); + pev->nextthink = gpGlobals->time + 0.1; + } + pev->angles.x += UTIL_AngleDiff(iangles.x, pev->angles.x) * 0.6; + //pev->angles.y += UTIL_AngleDiff(iangles.y, pev->angles.y) * 0.6; + pev->angles.z += UTIL_AngleDiff(iangles.z, pev->angles.z) * 0.6; + + pev->avelocity.x = pev->avelocity.y = pev->avelocity.z = 0; + } + else if (m_shape == SHAPE_NOROTATE) + { + pev->avelocity.x = pev->avelocity.y = pev->avelocity.z = 0; + Vector iangles = spawnAngles; + if (fabs(UTIL_AngleDiff(iangles.x, pev->angles.x)) > 0.1 || + fabs(UTIL_AngleDiff(iangles.y, pev->angles.y)) > 0.1 || + fabs(UTIL_AngleDiff(iangles.z, pev->angles.z)) > 0.1) + { + SetThink( &CProp::AngleThink); + pev->nextthink = gpGlobals->time + 0.1; + } + pev->angles.x += UTIL_AngleDiff(iangles.x, pev->angles.x) * 0.6; + pev->angles.y += UTIL_AngleDiff(iangles.y, pev->angles.y) * 0.6; + pev->angles.z += UTIL_AngleDiff(iangles.z, pev->angles.z) * 0.6; + } + else if (m_shape == SHAPE_GENERIC) + { + float ianglex = 0, ianglez = 0, imaxanglediff=360.0f; + // if first number is zero, it is angle + // all other zeroes is array end + for( int i = 0; (i < 10) && ( (i == 0 ) || m_iaCustomAnglesX[i] ); i++) + { + float anglediff = fabs(UTIL_AngleDiff(pev->angles.x, m_iaCustomAnglesX[i])); + if( imaxanglediff > anglediff ) + { + ianglex = m_iaCustomAnglesX[i]; + imaxanglediff = anglediff; + } + } + imaxanglediff=360.0f; + for( int i = 0; (i < 10) && ( (i == 0 ) || m_iaCustomAnglesZ[i] ); i++) + { + float anglediff = fabs(UTIL_AngleDiff(pev->angles.z, m_iaCustomAnglesZ[i])); + if( imaxanglediff > anglediff ) + { + ianglez = m_iaCustomAnglesZ[i]; + imaxanglediff = anglediff; + } + } + if (fabs(UTIL_AngleDiff(ianglex, pev->angles.x)) > 0.1 || + fabs(UTIL_AngleDiff(ianglez, pev->angles.z)) > 0.1 ) + { + SetThink( &CProp::AngleThink); + pev->nextthink = gpGlobals->time + 0.1; + } + pev->angles.x += UTIL_AngleDiff(ianglex, pev->angles.x) * 0.6; + pev->angles.z += UTIL_AngleDiff(ianglez, pev->angles.z) * 0.6; + pev->avelocity.x = pev->avelocity.y = pev->avelocity.z = 0; + } + pev->angles.x = UTIL_AngleMod(pev->angles.x); + pev->angles.y = UTIL_AngleMod(pev->angles.y); + pev->angles.z = UTIL_AngleMod(pev->angles.z); } int CProp::TakeDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType) { - Vector r = (pevInflictor->origin - pev->origin); - if (flDamage > 200 && ((CBaseEntity*)GET_PRIVATE(ENT(pevAttacker)))->IsPlayer()) - m_attacker = ENT(pevAttacker); - DeployThink(); - - pev->velocity = r * flDamage / -7; - pev->avelocity.x = pev->avelocity.x*0.5 + RANDOM_FLOAT(100, -100); - - // now some func_breakable code - - if ( !(pev->spawnflags & SF_PROP_BREAKABLE ) ) - return 0; - // Breakables take double damage from the crowbar - if ( bitsDamageType & DMG_CLUB ) - flDamage *= 2; - - // Boxes / glass / etc. don't take much poison damage, just the impact of the dart - consider that 10% - if ( bitsDamageType & DMG_POISON ) - flDamage *= 0.1; - g_vecAttackDir = r.Normalize(); - - // do the damage - pev->health -= flDamage; - if (pev->health <= 0) - { - Killed( VARS(m_attacker), GIB_NORMAL ); - Die(); - return 0; - } - - // Make a shard noise each time func breakable is hit. - // Don't play shard noise if cbreakable actually died. - - DamageSound(); - return 1; + Vector r = (pevInflictor->origin - pev->origin); + if (flDamage > 200 && ((CBaseEntity*)GET_PRIVATE(ENT(pevAttacker)))->IsPlayer()) + m_attacker = ENT(pevAttacker); + DeployThink(); + + pev->velocity = r * flDamage / -7; + pev->avelocity.x = pev->avelocity.x*0.5 + RANDOM_FLOAT(100, -100); + + // now some func_breakable code + + if ( !(pev->spawnflags & SF_PROP_BREAKABLE ) ) + return 0; + // Breakables take double damage from the crowbar + if ( bitsDamageType & DMG_CLUB ) + flDamage *= 2; + + // Boxes / glass / etc. don't take much poison damage, just the impact of the dart - consider that 10% + if ( bitsDamageType & DMG_POISON ) + flDamage *= 0.1; + g_vecAttackDir = r.Normalize(); + + // do the damage + pev->health -= flDamage; + if (pev->health <= 0) + { + Killed( VARS(m_attacker), GIB_NORMAL ); + Die(); + return 0; + } + + // Make a shard noise each time func breakable is hit. + // Don't play shard noise if cbreakable actually died. + + DamageSound(); + return 1; } void CProp::KeyValue( KeyValueData* pkvd ) { - ALERT( at_console, "%s %s\n", pkvd->szKeyName, pkvd->szValue); - // UNDONE_WC: explicitly ignoring these fields, but they shouldn't be in the map file! - if (FStrEq(pkvd->szKeyName, "explosion")) - { - if (!stricmp(pkvd->szValue, "directed")) - m_Explosion = expDirected; - else if (!stricmp(pkvd->szValue, "random")) - m_Explosion = expRandom; - else - m_Explosion = expRandom; - - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "material")) - { - int i = atoi( pkvd->szValue); - - // 0:glass, 1:metal, 2:flesh, 3:wood - - if ((i < 0) || (i >= matLastMaterial)) - m_Material = matWood; - else - m_Material = (Materials)i; - - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "shape")) - { - int i = atoi( pkvd->szValue); - - if ((i < 0) || (i >= SHAPE_NOROTATE)) - m_shape = SHAPE_NOROTATE; - else - m_shape = (PropShape)i; - - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "gibmodel") ) - { - m_iszGibModel = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "explodemagnitude") ) - { - ExplosionSetMagnitude( atoi( pkvd->szValue ) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "respawntime") ) - { - m_flRespawnTime = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "customanglesx")) - { - UTIL_StringToIntArray( m_iaCustomAnglesX, ARRAYSIZE( m_iaCustomAnglesX ), pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "customanglesz")) - { - UTIL_StringToIntArray( m_iaCustomAnglesZ, ARRAYSIZE( m_iaCustomAnglesZ ), pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "hmin")) - { - UTIL_StringToVector( minsH, pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "hmax")) - { - UTIL_StringToVector( maxsH, pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "vmin")) - { - UTIL_StringToVector( minsV, pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "vmax")) - { - UTIL_StringToVector( maxsV, pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); + ALERT( at_console, "%s %s\n", pkvd->szKeyName, pkvd->szValue); + // UNDONE_WC: explicitly ignoring these fields, but they shouldn't be in the map file! + if (FStrEq(pkvd->szKeyName, "explosion")) + { + if (!stricmp(pkvd->szValue, "directed")) + m_Explosion = expDirected; + else if (!stricmp(pkvd->szValue, "random")) + m_Explosion = expRandom; + else + m_Explosion = expRandom; + + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "material")) + { + int i = atoi( pkvd->szValue); + + // 0:glass, 1:metal, 2:flesh, 3:wood + + if ((i < 0) || (i >= matLastMaterial)) + m_Material = matWood; + else + m_Material = (Materials)i; + + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "shape")) + { + int i = atoi( pkvd->szValue); + + if ((i < 0) || (i >= SHAPE_NOROTATE)) + m_shape = SHAPE_NOROTATE; + else + m_shape = (PropShape)i; + + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "gibmodel") ) + { + m_iszGibModel = ALLOC_STRING(pkvd->szValue); + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "explodemagnitude") ) + { + ExplosionSetMagnitude( atoi( pkvd->szValue ) ); + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "respawntime") ) + { + m_flRespawnTime = atof( pkvd->szValue ); + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "customanglesx")) + { + UTIL_StringToIntArray( m_iaCustomAnglesX, ARRAYSIZE( m_iaCustomAnglesX ), pkvd->szValue ); + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "customanglesz")) + { + UTIL_StringToIntArray( m_iaCustomAnglesZ, ARRAYSIZE( m_iaCustomAnglesZ ), pkvd->szValue ); + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "hmin")) + { + UTIL_StringToVector( minsH, pkvd->szValue ); + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "hmax")) + { + UTIL_StringToVector( maxsH, pkvd->szValue ); + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "vmin")) + { + UTIL_StringToVector( minsV, pkvd->szValue ); + pkvd->fHandled = TRUE; + } + else if (FStrEq(pkvd->szKeyName, "vmax")) + { + UTIL_StringToVector( maxsV, pkvd->szValue ); + pkvd->fHandled = TRUE; + } + else + CBaseEntity::KeyValue( pkvd ); }