diff --git a/reactivedrop/fgd/reactivedrop.fgd b/reactivedrop/fgd/reactivedrop.fgd index 2694e4023..31bf59bef 100644 --- a/reactivedrop/fgd/reactivedrop.fgd +++ b/reactivedrop/fgd/reactivedrop.fgd @@ -149,6 +149,8 @@ input SetExcluded( string ) : "Change the NPC class excluded from collisions" input SetInvert( integer ) : "Set the state of inversion for NPC class exclusion (0 or 1)" input AllowFade( integer ) : "Enable or disable fading (0 or 1)" + input SetCollideWithGrenades(integer) : "Change CollideWithGrenades at runtime (0, 1 or 2)" + input SetCollideWithMarines(integer) : "Enable or disable marine collisions (0 or 1)" ] @PointClass base(prop_dynamic_base, EnableDisable) sphere(fademindist) sphere(fademaxdist) studioprop() = prop_asw_fade : diff --git a/src/game/server/hl2/grenade_spit.cpp b/src/game/server/hl2/grenade_spit.cpp index 8b194bcd1..88ffc2be8 100644 --- a/src/game/server/hl2/grenade_spit.cpp +++ b/src/game/server/hl2/grenade_spit.cpp @@ -71,7 +71,7 @@ void CGrenadeSpit::Spawn( void ) SetFriction( 0.8f ); SetCollisionGroup( ASW_COLLISION_GROUP_NPC_GRENADES ); - CFunc_ASW_Fade::DisableCollisionsWithGrenade( this ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); AddEFlags( EFL_FORCE_CHECK_TRANSMIT ); diff --git a/src/game/server/hl2/npc_zombine.cpp b/src/game/server/hl2/npc_zombine.cpp index 19c9cf6de..6748cdf54 100644 --- a/src/game/server/hl2/npc_zombine.cpp +++ b/src/game/server/hl2/npc_zombine.cpp @@ -379,7 +379,7 @@ void CNPC_Zombine::DropGrenade( Vector vDir ) m_hGrenade->SetMoveType( MOVETYPE_VPHYSICS ); m_hGrenade->SetSolid( SOLID_VPHYSICS ); m_hGrenade->SetCollisionGroup( ASW_COLLISION_GROUP_GRENADES ); - CFunc_ASW_Fade::DisableCollisionsWithGrenade( m_hGrenade ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( m_hGrenade ); m_hGrenade->CreateVPhysics(); } diff --git a/src/game/server/swarm/asw_bait.cpp b/src/game/server/swarm/asw_bait.cpp index eb88fd870..fd22e331a 100644 --- a/src/game/server/swarm/asw_bait.cpp +++ b/src/game/server/swarm/asw_bait.cpp @@ -7,6 +7,7 @@ #include "asw_shareddefs.h" #include "ai_senses.h" #include "asw_gamerules.h" +#include "func_asw_fade.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -58,6 +59,7 @@ void CASW_Bait::Spawn( void ) SetCollisionGroup( ASW_COLLISION_GROUP_IGNORE_NPCS ); //CreateVPhysics(); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); // Tumble in air QAngle vecAngVelocity( 0, random->RandomFloat ( -100, -500 ), 0 ); diff --git a/src/game/server/swarm/asw_flare_projectile.cpp b/src/game/server/swarm/asw_flare_projectile.cpp index 9ffa34c49..a81a2fce7 100644 --- a/src/game/server/swarm/asw_flare_projectile.cpp +++ b/src/game/server/swarm/asw_flare_projectile.cpp @@ -162,7 +162,7 @@ void CASW_Flare_Projectile::Spawn( void ) AddFlag( FL_OBJECT ); SetCollisionGroup( ASW_COLLISION_GROUP_GRENADES ); - CFunc_ASW_Fade::DisableCollisionsWithGrenade( this ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); // Tumble in air QAngle vecAngVelocity( 0, random->RandomFloat ( -100, -500 ), 0 ); diff --git a/src/game/server/swarm/asw_gas_grenade_projectile.cpp b/src/game/server/swarm/asw_gas_grenade_projectile.cpp index ade399da7..c236e589e 100644 --- a/src/game/server/swarm/asw_gas_grenade_projectile.cpp +++ b/src/game/server/swarm/asw_gas_grenade_projectile.cpp @@ -11,6 +11,7 @@ #include "particle_parse.h" #include "asw_generic_emitter_entity.h" #include "asw_radiation_volume.h" +#include "func_asw_fade.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -103,6 +104,8 @@ void CASW_Gas_Grenade_Projectile::Spawn( void ) SetCollisionGroup( ASW_COLLISION_GROUP_IGNORE_NPCS ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); + // Tumble in air QAngle vecAngVelocity( 0, random->RandomFloat ( -100, -500 ), 0 ); SetLocalAngularVelocity( vecAngVelocity ); diff --git a/src/game/server/swarm/asw_grenade_cluster.cpp b/src/game/server/swarm/asw_grenade_cluster.cpp index 00ca55cf3..21ea824f0 100644 --- a/src/game/server/swarm/asw_grenade_cluster.cpp +++ b/src/game/server/swarm/asw_grenade_cluster.cpp @@ -100,7 +100,7 @@ void CASW_Grenade_Cluster::Spawn( void ) SetFriction( asw_vindicator_grenade_friction.GetFloat() ); SetElasticity( asw_vindicator_grenade_elasticity.GetFloat() ); SetCollisionGroup( ASW_COLLISION_GROUP_GRENADES ); - CFunc_ASW_Fade::DisableCollisionsWithGrenade( this ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); SetTouch( &CASW_Grenade_Cluster::VGrenadeTouch ); diff --git a/src/game/server/swarm/asw_grenade_prifle.cpp b/src/game/server/swarm/asw_grenade_prifle.cpp index 95eaa861d..f531978da 100644 --- a/src/game/server/swarm/asw_grenade_prifle.cpp +++ b/src/game/server/swarm/asw_grenade_prifle.cpp @@ -12,6 +12,7 @@ #include "particle_parse.h" #include "asw_player.h" #include "asw_achievements.h" +#include "func_asw_fade.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -48,6 +49,7 @@ void CASW_Grenade_PRifle::Spawn() { BaseClass::Spawn(); SetModel( STUN_GRENADE_MODEL ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); } void CASW_Grenade_PRifle::Detonate() diff --git a/src/game/server/swarm/asw_grenade_vindicator.cpp b/src/game/server/swarm/asw_grenade_vindicator.cpp index c92e41560..0ed097d21 100644 --- a/src/game/server/swarm/asw_grenade_vindicator.cpp +++ b/src/game/server/swarm/asw_grenade_vindicator.cpp @@ -95,7 +95,7 @@ void CASW_Grenade_Vindicator::Spawn( void ) SetFriction( asw_vindicator_grenade_friction.GetFloat() ); SetElasticity( asw_vindicator_grenade_elasticity.GetFloat() ); SetCollisionGroup( ASW_COLLISION_GROUP_GRENADES ); - CFunc_ASW_Fade::DisableCollisionsWithGrenade( this ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); //CreateVPhysics(); SetTouch( &CASW_Grenade_Vindicator::VGrenadeTouch ); diff --git a/src/game/server/swarm/asw_laser_mine.cpp b/src/game/server/swarm/asw_laser_mine.cpp index 0f6a4f6e9..190fd3f66 100644 --- a/src/game/server/swarm/asw_laser_mine.cpp +++ b/src/game/server/swarm/asw_laser_mine.cpp @@ -82,7 +82,7 @@ void CASW_Laser_Mine::Spawn( void ) AddEffects( EF_NOSHADOW | EF_NORECEIVESHADOW ); SetCollisionGroup( ASW_COLLISION_GROUP_GRENADES ); - CFunc_ASW_Fade::DisableCollisionsWithGrenade( this ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); SetThink( &CASW_Laser_Mine::LaserThink ); SetNextThink( gpGlobals->curtime + 0.1f ); diff --git a/src/game/server/swarm/asw_marine.cpp b/src/game/server/swarm/asw_marine.cpp index aebc71d8b..14171720c 100644 --- a/src/game/server/swarm/asw_marine.cpp +++ b/src/game/server/swarm/asw_marine.cpp @@ -890,7 +890,7 @@ void CASW_Marine::Spawn( void ) UTIL_SetSize( this, GetHullMins(), GetHullMaxs() ); - CFunc_ASW_Fade::DisableCollisionsWithMarine( this ); + CFunc_ASW_Fade::ApplyMarineCollisionRules( this ); } unsigned int CASW_Marine::PhysicsSolidMaskForEntity( void ) const diff --git a/src/game/server/swarm/asw_mine.cpp b/src/game/server/swarm/asw_mine.cpp index 8c1070dcd..70443d668 100644 --- a/src/game/server/swarm/asw_mine.cpp +++ b/src/game/server/swarm/asw_mine.cpp @@ -56,7 +56,7 @@ void CASW_Mine::Spawn( void ) SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_TRIGGER ); SetCollisionGroup( ASW_COLLISION_GROUP_GRENADES ); - CFunc_ASW_Fade::DisableCollisionsWithGrenade( this ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); SetMoveType( MOVETYPE_FLYGRAVITY ); m_takedamage = DAMAGE_NO; m_bPrimed = false; diff --git a/src/game/server/swarm/asw_rocket.cpp b/src/game/server/swarm/asw_rocket.cpp index 7b4d5c7c9..c722e4a05 100644 --- a/src/game/server/swarm/asw_rocket.cpp +++ b/src/game/server/swarm/asw_rocket.cpp @@ -103,7 +103,7 @@ void CASW_Rocket::Spawn( void ) SetTouch( &CASW_Rocket::MissileTouch ); SetCollisionGroup( ASW_COLLISION_GROUP_PLAYER_MISSILE ); - CFunc_ASW_Fade::DisableCollisionsWithGrenade( this ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); SetThink( &CASW_Rocket::IgniteThink ); diff --git a/src/game/server/swarm/func_asw_fade.cpp b/src/game/server/swarm/func_asw_fade.cpp index 6d9ab4196..875f5261f 100644 --- a/src/game/server/swarm/func_asw_fade.cpp +++ b/src/game/server/swarm/func_asw_fade.cpp @@ -12,10 +12,12 @@ LINK_ENTITY_TO_CLASS( func_asw_fade, CFunc_ASW_Fade ); BEGIN_DATADESC( CFunc_ASW_Fade ) DEFINE_FIELD( m_bHasProxies, FIELD_BOOLEAN ), + DEFINE_KEYFIELD( m_nFadeOpacity, FIELD_CHARACTER, "fade_opacity" ), DEFINE_KEYFIELD( m_iCollideWithGrenades, FIELD_CHARACTER, "CollideWithGrenades" ), DEFINE_KEYFIELD( m_bCollideWithMarines, FIELD_BOOLEAN, "CollideWithMarines" ), - DEFINE_KEYFIELD( m_nFadeOpacity, FIELD_CHARACTER, "fade_opacity" ), DEFINE_INPUT( m_bAllowFade, FIELD_BOOLEAN, "AllowFade" ), + DEFINE_INPUTFUNC( FIELD_INTEGER, "SetCollideWithGrenades", SetGrenadeCollisionRules ), + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetCollideWithMarines", SetMarineCollisionRules ), END_DATADESC() IMPLEMENT_SERVERCLASS_ST( CFunc_ASW_Fade, DT_Func_ASW_Fade ) @@ -42,32 +44,92 @@ void CFunc_ASW_Fade::Spawn() Assert( m_iCollideWithGrenades <= 2 ); } -void CFunc_ASW_Fade::DisableCollisionsWithGrenade( CBaseEntity *pGrenade ) +void CFunc_ASW_Fade::ApplyGrenadeCollisionRules( CBaseEntity* pGrenade ) { - float flGrenadeZ = pGrenade->GetAbsOrigin().z; - string_t iszClassName = AllocPooledString( "func_asw_fade" ); + const float flGrenadeZ = pGrenade->GetAbsOrigin().z; + const string_t iszClassName = AllocPooledString( "func_asw_fade" ); - CFunc_ASW_Fade *pCeiling = NULL; - while ( ( pCeiling = assert_cast< CFunc_ASW_Fade * >( gEntList.FindEntityByClassnameFast( pCeiling, iszClassName ) ) ) != NULL ) + CFunc_ASW_Fade* pCeiling = nullptr; + while ( ( pCeiling = assert_cast( + gEntList.FindEntityByClassnameFast( pCeiling, iszClassName ) ) ) != nullptr ) { - if ( ( pCeiling->m_iCollideWithGrenades == 0 && pCeiling->GetAbsOrigin().z >= flGrenadeZ ) || pCeiling->m_iCollideWithGrenades == 2 ) + const bool bShouldDisable = + ( pCeiling->m_iCollideWithGrenades == 0 && pCeiling->GetAbsOrigin().z >= flGrenadeZ ) || + ( pCeiling->m_iCollideWithGrenades == 2 ); + + const bool bCurrentlyDisabled = PhysEntityCollisionsAreDisabled( pCeiling, pGrenade ); + + if ( bShouldDisable && !bCurrentlyDisabled ) { PhysDisableEntityCollisions( pCeiling, pGrenade ); } + else if ( !bShouldDisable && bCurrentlyDisabled ) + { + PhysEnableEntityCollisions( pCeiling, pGrenade ); + } } } -void CFunc_ASW_Fade::DisableCollisionsWithMarine( CBaseEntity *pMarine ) +void CFunc_ASW_Fade::ApplyMarineCollisionRules( CBaseEntity* pMarine ) { - string_t iszClassName = AllocPooledString( "func_asw_fade" ); + const string_t iszClassName = AllocPooledString( "func_asw_fade" ); - CFunc_ASW_Fade *pCeiling = NULL; - while ( ( pCeiling = assert_cast< CFunc_ASW_Fade * >( gEntList.FindEntityByClassnameFast( pCeiling, iszClassName ) ) ) != NULL ) + CFunc_ASW_Fade* pCeiling = nullptr; + while ( ( pCeiling = assert_cast( + gEntList.FindEntityByClassnameFast( pCeiling, iszClassName ) ) ) != nullptr ) { - if ( !pCeiling->m_bCollideWithMarines ) + const bool bShouldDisable = !pCeiling->m_bCollideWithMarines; + const bool bCurrentlyDisabled = PhysEntityCollisionsAreDisabled( pCeiling, pMarine ); + + if ( bShouldDisable && !bCurrentlyDisabled ) { PhysDisableEntityCollisions( pCeiling, pMarine ); } + else if ( !bShouldDisable && bCurrentlyDisabled ) + { + PhysEnableEntityCollisions( pCeiling, pMarine ); + } + } +} + +void CFunc_ASW_Fade::SetGrenadeCollisionRules( inputdata_t& inputdata ) +{ + m_iCollideWithGrenades = clamp( inputdata.value.Int(), 0, 2 ); + + static const char* pszExplosiveClasses[] = { + "asw_mine", + "npc_grenade_frag", + "asw_rocket", + "grenadespit", + "asw_missile_round", + "asw_grenade_cluster", + "asw_flare_projectile", + "asw_laser_mine", + "asw_grenade_vindicator", + "asw_gas_grenade_projectile", + "asw_bait", + "asw_grenade_prifle", + nullptr + }; + + for ( const char** pszClass = pszExplosiveClasses; *pszClass; ++pszClass ) + { + CBaseEntity* pGrenade = NULL; + while ( ( pGrenade = gEntList.FindEntityByClassname( pGrenade, *pszClass ) ) != NULL ) + { + ApplyGrenadeCollisionRules( pGrenade ); + } + } +} + +void CFunc_ASW_Fade::SetMarineCollisionRules( inputdata_t& inputdata ) +{ + m_bCollideWithMarines = !!inputdata.value.Int(); + + CBaseEntity* pMarine = NULL; + while ( ( pMarine = gEntList.FindEntityByClassname( pMarine, "asw_marine" ) ) != NULL ) + { + ApplyMarineCollisionRules( pMarine ); } } diff --git a/src/game/server/swarm/func_asw_fade.h b/src/game/server/swarm/func_asw_fade.h index 055fb4e7c..0eaa65326 100644 --- a/src/game/server/swarm/func_asw_fade.h +++ b/src/game/server/swarm/func_asw_fade.h @@ -21,8 +21,11 @@ class CFunc_ASW_Fade : public CFuncBrush virtual void Spawn() override; bool ShouldFade( CASW_Inhabitable_NPC *pNPC ); - static void DisableCollisionsWithGrenade( CBaseEntity *pGrenade ); - static void DisableCollisionsWithMarine( CBaseEntity *pMarine ); + static void ApplyGrenadeCollisionRules( CBaseEntity *pGrenade ); + static void ApplyMarineCollisionRules( CBaseEntity *pMarine ); + + void SetGrenadeCollisionRules( inputdata_t& inputdata ); + void SetMarineCollisionRules( inputdata_t& inputdata ); CNetworkVar( bool, m_bHasProxies ); // 0 = only when grenade spawns above the brush diff --git a/src/game/shared/swarm/asw_missile_round_shared.cpp b/src/game/shared/swarm/asw_missile_round_shared.cpp index 4b4e3f106..a86460eb8 100644 --- a/src/game/shared/swarm/asw_missile_round_shared.cpp +++ b/src/game/shared/swarm/asw_missile_round_shared.cpp @@ -95,7 +95,7 @@ void CASW_Missile_Round::Spawn( void ) SetSolid( SOLID_NONE ); SetGravity( m_ShotDef.m_flGravity ); SetCollisionGroup( ASW_COLLISION_GROUP_ALIEN_MISSILE ); - CFunc_ASW_Fade::DisableCollisionsWithGrenade( this ); + CFunc_ASW_Fade::ApplyGrenadeCollisionRules( this ); SetTouch( &CASW_Missile_Round::Touch );