diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/tf2/tf_obj_barbed_wire.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/server/tf2/tf_obj_barbed_wire.cpp')
| -rw-r--r-- | game/server/tf2/tf_obj_barbed_wire.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/game/server/tf2/tf_obj_barbed_wire.cpp b/game/server/tf2/tf_obj_barbed_wire.cpp new file mode 100644 index 0000000..5666d36 --- /dev/null +++ b/game/server/tf2/tf_obj_barbed_wire.cpp @@ -0,0 +1,239 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "tf_obj_barbed_wire.h" +#include "tf_player.h" +#include "basetfvehicle.h" +#include "engine/IEngineSound.h" +#include "te_effect_dispatch.h" +#include "ndebugoverlay.h" + +#define BARBED_WIRE_MINS Vector(-5, -5, 0) +#define BARBED_WIRE_MAXS Vector( 5, 5, 40) +#define BARBED_WIRE_MODEL "models/objects/obj_barbed_wire.mdl" + +#define MAX_BARBED_WIRE_DISTANCE 768 +#define BARBED_WIRE_THINK_CONTEXT "BarbedWireThinkContext" + +#define BARBED_WIRE_THINK_INTERVAL 0.2 + +ConVar obj_barbed_wire_damage( "obj_barbed_wire_damage", "80" ); +ConVar obj_barbed_wire_health( "obj_barbed_wire_health", "100" ); + + +IMPLEMENT_SERVERCLASS_ST( CObjectBarbedWire, DT_ObjectBarbedWire ) + SendPropEHandle( SENDINFO( m_hConnectedTo ) ) +END_SEND_TABLE() + + +LINK_ENTITY_TO_CLASS( obj_barbed_wire, CObjectBarbedWire ); +PRECACHE_REGISTER( obj_barbed_wire ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CObjectBarbedWire::CObjectBarbedWire() +{ + m_iHealth = obj_barbed_wire_health.GetInt(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CObjectBarbedWire::Precache() +{ + PrecacheModel( BARBED_WIRE_MODEL ); + BaseClass::Precache(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CObjectBarbedWire::Spawn() +{ + Precache(); + + SetModel( BARBED_WIRE_MODEL ); + SetSolid( SOLID_BBOX ); + SetType( OBJ_BARBED_WIRE ); + UTIL_SetSize(this, BARBED_WIRE_MINS, BARBED_WIRE_MAXS ); + + // Set our flags. + m_fObjectFlags |= OF_DOESNT_NEED_POWER | OF_SUPPRESS_APPEAR_ON_MINIMAP | OF_SUPPRESS_NOTIFY_UNDER_ATTACK | OF_ALLOW_REPEAT_PLACEMENT; + + // Get the ball rolling here. + BarbedWireThink(); + + BaseClass::Spawn(); +} + +//----------------------------------------------------------------------------- +// Purpose: Enumerator +//----------------------------------------------------------------------------- +class CBarbedWireEnumerator : public IEntityEnumerator +{ +public: + CBarbedWireEnumerator( CObjectBarbedWire *pWire, Ray_t *pRay, int contentsMask ) + { + m_pWire = pWire; + m_pRay = pRay; + m_ContentsMask = contentsMask; + m_aDamagedEntities.Purge(); + } + + virtual bool EnumEntity( IHandleEntity *pHandleEntity ) + { + CBaseEntity *pEntity = gEntList.GetBaseEntity( pHandleEntity->GetRefEHandle() ); + if ( pEntity && !m_pWire->InSameTeam( pEntity ) ) + { + trace_t tr; + enginetrace->ClipRayToEntity( *m_pRay, m_ContentsMask, pHandleEntity, &tr ); + if ( tr.fraction < 1.0f ) + { + // Add them to the list & damage them later. + // Done this way so entities don't remove themselves from leaves while we're tracing + if ( m_aDamagedEntities.Find( pEntity ) == m_aDamagedEntities.InvalidIndex() ) + { + m_aDamagedEntities.AddToTail( pEntity ); + } + } + } + + return true; + } + + void DamageEntities( void ) + { + int iSize = m_aDamagedEntities.Count(); + for ( int i = iSize-1; i >= 0; i-- ) + { + CBaseEntity *pEntity = m_aDamagedEntities[i].Get(); + if ( pEntity ) + { + // DMG_CRUSH added so there's no physics force generated + CTakeDamageInfo info( m_pWire, m_pWire->GetBuilder(), obj_barbed_wire_damage.GetFloat() * BARBED_WIRE_THINK_INTERVAL, DMG_SLASH | DMG_CRUSH ); + pEntity->TakeDamage( info ); + + // Bloodspray + CEffectData data; + data.m_vOrigin = pEntity->WorldSpaceCenter(); + data.m_vNormal = Vector(0,0,1); + data.m_flScale = 4; + data.m_fFlags = FX_BLOODSPRAY_ALL; + data.m_nEntIndex = pEntity->entindex(); + DispatchEffect( "tf2blood", data ); + } + } + } + +private: + CObjectBarbedWire *m_pWire; + int m_ContentsMask; + Ray_t + *m_pRay; + CUtlVector< EHANDLE > m_aDamagedEntities; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CObjectBarbedWire::BarbedWireThink( void ) +{ + // Cut the rope if we're too far from the entity it's attached to. + if ( m_hConnectedTo.Get() ) + { + if ( (WorldSpaceCenter() - m_hConnectedTo->WorldSpaceCenter()).Length() > MAX_BARBED_WIRE_DISTANCE ) + { + m_hConnectedTo = NULL; + } + + if ( m_hConnectedTo ) + { + Ray_t ray; + ray.Init( WorldSpaceCenter(), m_hConnectedTo->WorldSpaceCenter() ); + + //NDebugOverlay::Line( WorldSpaceCenter(), m_hConnectedTo->WorldSpaceCenter(), 255,255,255, false, 0.1 ); + //NDebugOverlay::Box( WorldSpaceCenter(), -Vector(5,5,5), Vector(5,5,5), 0,255,0,8, 0.1 ); + //NDebugOverlay::Box( m_hConnectedTo->WorldSpaceCenter(), -Vector(6,6,6), Vector(6,6,6), 255,255,255,8, 0.1 ); + + CBarbedWireEnumerator bwEnum( this, &ray, MASK_SHOT_HULL ); + enginetrace->EnumerateEntities( ray, false, &bwEnum ); + bwEnum.DamageEntities(); + } + } + + SetContextThink( BarbedWireThink, gpGlobals->curtime + BARBED_WIRE_THINK_INTERVAL, BARBED_WIRE_THINK_CONTEXT ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CObjectBarbedWire::StartPlacement( CBaseTFPlayer *pPlayer ) +{ + if ( pPlayer && !m_hConnectedTo ) + { + // Automatically connect to the nearest barbed wire on our team. + float flClosest = 1e24; + CObjectBarbedWire *pClosest = NULL; + + CBaseEntity *pCur = gEntList.FirstEnt(); + while ( pCur ) + { + CObjectBarbedWire *pWire = dynamic_cast< CObjectBarbedWire* >( pCur ); + if ( pWire ) + { + if ( pWire->GetTeamNumber() == pPlayer->GetTeamNumber() ) + { + float flDist = (pWire->WorldSpaceCenter() - pPlayer->WorldSpaceCenter()).Length(); + if ( flDist < flClosest ) + { + flClosest = flDist; + pClosest = pWire; + } + } + } + + pCur = gEntList.NextEnt( pCur ); + } + + if ( pClosest ) + { + m_hConnectedTo = pClosest; + } + } + + BaseClass::StartPlacement( pPlayer ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CObjectBarbedWire::PreStartBuilding() +{ + const CObjectBarbedWire *pWire = dynamic_cast< const CObjectBarbedWire* >( m_hBuiltOnEntity.Get() ); + if ( pWire ) + { + // Reconnect the wire to this entity and don't build yet. + m_hConnectedTo = pWire; + + return false; + } + else + { + // Go ahead and build. + return true; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CObjectBarbedWire::FinishedBuilding() +{ + BaseClass::FinishedBuilding(); +} + |