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_func_weldable_door.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_func_weldable_door.cpp')
| -rw-r--r-- | game/server/tf2/tf_func_weldable_door.cpp | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/game/server/tf2/tf_func_weldable_door.cpp b/game/server/tf2/tf_func_weldable_door.cpp new file mode 100644 index 0000000..3e278e4 --- /dev/null +++ b/game/server/tf2/tf_func_weldable_door.cpp @@ -0,0 +1,399 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Func door that's weldable shut +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "beam_shared.h" +#include "tf_player.h" +#include "tf_team.h" +#include "tf_basecombatweapon.h" +#include "tf_func_weldable_door.h" +#include "IEffects.h" + + +LINK_ENTITY_TO_CLASS( func_door_weldable, CWeldableDoor ); + +BEGIN_DATADESC( CWeldableDoor ) + + // keys + DEFINE_KEYFIELD( m_iszWeldPoints, FIELD_STRING, "weldpoints" ), + +END_DATADESC() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeldableDoor::Spawn( void ) +{ + BaseClass::Spawn(); + + m_hWeldingPlayer = NULL; + m_flMaxWeldedPercentage = 0.0; + m_iWeldLeader = WL_UNASSIGNED; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeldableDoor::Activate( void ) +{ + BaseClass::Activate(); + + // Find my weld points + if ( !m_iszWeldPoints ) + { + Msg( "func_weldable_door without weldpoints specified.\n" ); + UTIL_Remove( this ); + return; + } + + // Find the weld points. Doors will almost always have multiple weld point pairs. + CWeldPoint *pWeldStartPoint = NULL; + while( (pWeldStartPoint = (CWeldPoint*)gEntList.FindEntityByName( pWeldStartPoint, m_iszWeldPoints ) ) != NULL ) + { + // Does it have an endpoint specified? + if ( !pWeldStartPoint->m_target ) + { + Msg( "func_weldable_door weldpoint '%s' didn't have an endpoint specified.\n", STRING(m_iszWeldPoints) ); + continue; + } + + // Find the endpoint for this startpoint + CWeldPoint *pWeldEndPoint = (CWeldPoint*)gEntList.FindEntityByName( NULL, pWeldStartPoint->m_target ); + if ( pWeldEndPoint ) + { + // Connect the start point to the endpoint + pWeldStartPoint->SetEndPoint( pWeldEndPoint->GetLocalOrigin() ); + + // Add it to the list + m_aWeldPoints.AddToTail( pWeldStartPoint ); + } + else + { + Msg( "func_weldable_door weldpoint couldn't find it's endpoint of '%s'.\n", STRING(pWeldStartPoint->m_target) ); + continue; + } + } + + // Did we find any weldpoint pairs? + if ( m_aWeldPoints.Size() == 0 ) + { + Msg( "func_weldable_door couldn't find any weldpoints for '%s'.\n", STRING(m_iszWeldPoints) ); + UTIL_Remove( this ); + return; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Returns true if someone's allowed to start welding on this door +//----------------------------------------------------------------------------- +bool CWeldableDoor::IsWeldable( CBaseTFPlayer *pWeldee ) +{ + // Can't be welded if I'm open + if ( m_toggle_state != TS_AT_BOTTOM ) + return false; + + // Can't be welded if I'm already being welded by someone else + if ( m_hWeldingPlayer != NULL && (((CBaseEntity*)m_hWeldingPlayer) != pWeldee) ) + return false; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Return the weld leader. +// Doors can be made up of multiple door entities, so one of them needs to volunteer to control the welding. +//----------------------------------------------------------------------------- +CWeldableDoor *CWeldableDoor::GetWeldLeader( void ) +{ + // Am I the leader? + if ( m_iWeldLeader == WL_WELD_LEADER ) + return this; + + // If this guy's unassigned, he's volunteering + if ( m_iWeldLeader == WL_UNASSIGNED ) + { + m_iWeldLeader = WL_WELD_LEADER; + + // Tell all other friends they're children + CBaseEntity *pTarget = NULL; + if ( GetEntityName() != NULL_STRING ) + { + while ( (pTarget = gEntList.FindEntityByName( pTarget, GetEntityName() )) != NULL ) + { + if ( pTarget != this ) + { + CWeldableDoor *pWeldableDoor = dynamic_cast< CWeldableDoor * >( pTarget ); + if ( pWeldableDoor ) + { + pWeldableDoor->m_iWeldLeader = WL_WELD_CHILD; + } + } + } + } + + return this; + } + + // We're not the leader. so find him + CBaseEntity *pTarget = NULL; + if ( GetEntityName() != NULL_STRING ) + { + while ( (pTarget = gEntList.FindEntityByName( pTarget, GetEntityName() )) != NULL ) + { + if ( pTarget != this ) + { + CWeldableDoor *pWeldableDoor = dynamic_cast< CWeldableDoor * >( pTarget ); + if ( pWeldableDoor && pWeldableDoor->m_iWeldLeader == WL_WELD_LEADER ) + return pWeldableDoor; + } + } + } + + return NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: The Player's going to start welding this door. +//----------------------------------------------------------------------------- +void CWeldableDoor::StartWelding( CBaseTFPlayer *pWeldee ) +{ + m_hWeldingPlayer = pWeldee; + + // If this is the weld leader, tell all the door pieces that the player's welding them + if ( m_iWeldLeader == WL_WELD_LEADER ) + { + CBaseEntity *pTarget = NULL; + if ( GetEntityName() != NULL_STRING ) + { + while ( (pTarget = gEntList.FindEntityByName( pTarget, GetEntityName() )) != NULL ) + { + if ( pTarget != this ) + { + CWeldableDoor *pWeldableDoor = dynamic_cast< CWeldableDoor * >( pTarget ); + if ( pWeldableDoor ) + { + pWeldableDoor->StartWelding( pWeldee ); + } + } + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: The player's stopped welding this door +//----------------------------------------------------------------------------- +void CWeldableDoor::StopWelding( void ) +{ + m_hWeldingPlayer = NULL; + + // If this is the weld leader, tell all the door pieces that the player's stopped welding them + if ( m_iWeldLeader == WL_WELD_LEADER ) + { + CBaseEntity *pTarget = NULL; + if ( GetEntityName() != NULL_STRING ) + { + while ( (pTarget = gEntList.FindEntityByName( pTarget, GetEntityName() )) != NULL ) + { + if ( pTarget != this ) + { + CWeldableDoor *pWeldableDoor = dynamic_cast< CWeldableDoor * >( pTarget ); + if ( pWeldableDoor ) + { + pWeldableDoor->StopWelding(); + } + } + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Return the amount the door's been welded +//----------------------------------------------------------------------------- +float CWeldableDoor::GetWeldPercentage( void ) +{ + return m_flWeldedPercentage; +} + +//----------------------------------------------------------------------------- +// Purpose: Update the amount the door's been welded +//----------------------------------------------------------------------------- +void CWeldableDoor::UpdateWeld( bool bCutting, float flWeldPercentage ) +{ + if ( m_flMaxWeldedPercentage < flWeldPercentage ) + m_flMaxWeldedPercentage = flWeldPercentage; + m_flWeldedPercentage = flWeldPercentage; + + // Did we cut away the entire weld? + if ( m_flWeldedPercentage <= 0.0 ) + { + // Clear welded + m_flMaxWeldedPercentage = 0.0; + + if ( m_bLocked ) + { + // Unlock all the pieces of this door + m_bLocked = false; + + CBaseEntity *pTarget = NULL; + if ( GetEntityName() != NULL_STRING ) + { + while ( (pTarget = gEntList.FindEntityByName( pTarget, GetEntityName() )) != NULL ) + { + if ( pTarget != this ) + { + CWeldableDoor *pWeldableDoor = dynamic_cast< CWeldableDoor * >( pTarget ); + if ( pWeldableDoor ) + { + pWeldableDoor->Unlock(); + } + } + } + } + } + } + else + { + if ( !m_bLocked ) + { + // Lock all the pieces of this door + m_bLocked = true; + + CBaseEntity *pTarget = NULL; + if ( GetEntityName() != NULL_STRING ) + { + while ( (pTarget = gEntList.FindEntityByName( pTarget, GetEntityName() )) != NULL ) + { + if ( pTarget != this ) + { + CWeldableDoor *pWeldableDoor = dynamic_cast< CWeldableDoor * >( pTarget ); + if ( pWeldableDoor ) + { + pWeldableDoor->Lock(); + } + } + } + } + } + } + + // Update the beams + for ( int i = 0; i < m_aWeldPoints.Size(); i++ ) + { + // First time we've updated? + if ( m_aWeldBeams.Size() <= i ) + { + CBeam *pBeam = CBeam::BeamCreate( "sprites/physbeam.vmt", 4.0 ); + pBeam->SetColor( 128, 128, 128 ); + pBeam->SetBrightness( 128 ); + pBeam->PointsInit( m_aWeldPoints[i]->GetStartPoint(), m_aWeldPoints[i]->GetEndPoint() ); + m_aWeldBeams.AddToTail( pBeam ); + } + if ( m_aCutBeams.Size() <= i ) + { + CBeam *pBeam = CBeam::BeamCreate( "sprites/physbeam.vmt", 4.0 ); + pBeam->SetColor( 255, 255, 255 ); + pBeam->SetBrightness( 255 ); + pBeam->PointsInit( m_aWeldPoints[i]->GetStartPoint(), m_aWeldPoints[i]->GetEndPoint() ); + m_aCutBeams.AddToTail( pBeam ); + } + + // Figure out how far we've welded + Vector vecLine = ( m_aWeldPoints[i]->GetEndPoint() - m_aWeldPoints[i]->GetStartPoint()); + float flLength = vecLine.Length(); + VectorNormalize(vecLine); + vecLine = vecLine * (flLength * flWeldPercentage); + Vector vecWeldPoint = m_aWeldPoints[i]->GetStartPoint() + vecLine; + + // Update the beams + m_aWeldBeams[i]->SetStartPos( m_aWeldPoints[i]->GetStartPoint() ); + m_aWeldBeams[i]->SetEndPos( vecWeldPoint ); + m_aWeldBeams[i]->RelinkBeam(); + if ( flWeldPercentage <= m_flMaxWeldedPercentage ) + { + // Get the cut point + VectorNormalize(vecLine); + vecLine = vecLine * (flLength * m_flMaxWeldedPercentage); + Vector vecCutPoint = m_aWeldPoints[i]->GetStartPoint() + vecLine; + + m_aCutBeams[i]->SetEndPos( vecWeldPoint ); + m_aCutBeams[i]->SetStartPos( vecCutPoint ); + m_aCutBeams[i]->RelinkBeam(); + } + + // Some sparks + if ( random->RandomInt(0,2) == 0 ) + { + g_pEffects->Sparks( vecWeldPoint ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Find a weld point to watch for this player +//----------------------------------------------------------------------------- +Vector CWeldableDoor::GetPlayerWeldPoint( void ) +{ + CBaseTFPlayer *pPlayer = (CBaseTFPlayer *)(CBaseEntity*)m_hWeldingPlayer; + Vector vecSrc = pPlayer->Weapon_ShootPosition( ); + trace_t tr; + + for ( int i = 0; i < m_aWeldPoints.Size(); i++ ) + { + // Figure out where the weldpoint is + Vector vecLine = ( m_aWeldPoints[i]->GetEndPoint() - m_aWeldPoints[i]->GetStartPoint()); + float flLength = vecLine.Length(); + VectorNormalize(vecLine); + vecLine = vecLine * (flLength * m_flWeldedPercentage); + Vector vecWeldPoint = m_aWeldPoints[i]->GetStartPoint() + vecLine; + + // Is the weld point visible to our player? + UTIL_TraceLine( vecSrc, vecWeldPoint, MASK_SOLID, pPlayer, TFCOLLISION_GROUP_WEAPON, &tr ); + if ( tr.fraction == 1.0 ) + return vecWeldPoint; + } + + return vec3_origin; +} + + +//============================================================================================================ +// WELD POINTS +//============================================================================================================ + +LINK_ENTITY_TO_CLASS( info_weldpoint, CWeldPoint ); + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeldPoint::Spawn( void ) +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CWeldPoint::SetEndPoint( const Vector &vecEndPoint ) +{ + m_vecEndPoint = vecEndPoint; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const Vector &CWeldPoint::GetStartPoint( void ) const +{ + return GetLocalOrigin(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const Vector &CWeldPoint::GetEndPoint( void ) const +{ + return m_vecEndPoint; +} |