Advertisement
Guest User

Untitled

a guest
Jul 3rd, 2018
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.52 KB | None | 0 0
  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Special handling for hl2 usable ladders
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "hl_gamemovement.h"
  8. #include "in_buttons.h"
  9. #include "utlrbtree.h"
  10. #include "hl2_shareddefs.h"
  11.  
  12. /*
  13. // MY CODE : Gravity Well
  14. #ifdef CLIENT_DLL
  15. #include "c_gravityplayer.h"
  16. #else
  17. #include "gravity_player.h"
  18. #endif
  19. //
  20. */
  21.  
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include "tier0/memdbgon.h"
  24.  
  25. static ConVar sv_autoladderdismount( "sv_autoladderdismount", "1", FCVAR_REPLICATED, "Automatically dismount from ladders when you reach the end (don't have to +USE)." );
  26. static ConVar sv_ladderautomountdot( "sv_ladderautomountdot", "0.4", FCVAR_REPLICATED, "When auto-mounting a ladder by looking up its axis, this is the tolerance for looking now directly along the ladder axis." );
  27.  
  28. static ConVar sv_ladder_useonly( "sv_ladder_useonly", "0", FCVAR_REPLICATED, "If set, ladders can only be mounted by pressing +USE" );
  29.  
  30. #define USE_DISMOUNT_SPEED 100
  31.  
  32. //-----------------------------------------------------------------------------
  33. // Purpose:
  34. //-----------------------------------------------------------------------------
  35. CHL2GameMovement::CHL2GameMovement()
  36. {
  37. }
  38.  
  39. //-----------------------------------------------------------------------------
  40. // Purpose:
  41. // Input : type -
  42. // Output : int
  43. //-----------------------------------------------------------------------------
  44. int CHL2GameMovement::GetCheckInterval( IntervalType_t type )
  45. {
  46. // HL2 ladders need to check every frame!!!
  47. if ( type == LADDER )
  48. return 1;
  49.  
  50. return BaseClass::GetCheckInterval( type );
  51. }
  52.  
  53. //-----------------------------------------------------------------------------
  54. // Purpose:
  55. // Output : Returns true on success, false on failure.
  56. //-----------------------------------------------------------------------------
  57. bool CHL2GameMovement::IsForceMoveActive()
  58. {
  59. LadderMove_t *lm = GetLadderMove();
  60. return lm->m_bForceLadderMove;
  61. }
  62.  
  63. //-----------------------------------------------------------------------------
  64. // Purpose: Debounce the USE button
  65. //-----------------------------------------------------------------------------
  66. void CHL2GameMovement::SwallowUseKey()
  67. {
  68. mv->m_nOldButtons |= IN_USE;
  69. player->m_afButtonPressed &= ~IN_USE;
  70.  
  71. GetHL2Player()->m_bPlayUseDenySound = false;
  72. }
  73.  
  74. #if !defined( CLIENT_DLL )
  75. // This is a simple helper class to reserver a player sized hull at a spot, owned by the current player so that nothing
  76. // can move into this spot and cause us to get stuck when we get there
  77. class CReservePlayerSpot : public CBaseEntity
  78. {
  79. DECLARE_CLASS( CReservePlayerSpot, CBaseEntity )
  80. public:
  81. static CReservePlayerSpot *ReserveSpot( CBasePlayer *owner, const Vector& org, const Vector& mins, const Vector& maxs, bool& validspot );
  82.  
  83. virtual void Spawn();
  84. };
  85.  
  86. CReservePlayerSpot *CReservePlayerSpot::ReserveSpot(
  87. CBasePlayer *owner, const Vector& org, const Vector& mins, const Vector& maxs, bool& validspot )
  88. {
  89. CReservePlayerSpot *spot = ( CReservePlayerSpot * )CreateEntityByName( "reserved_spot" );
  90. Assert( spot );
  91.  
  92. spot->SetAbsOrigin( org );
  93. UTIL_SetSize( spot, mins, maxs );
  94. spot->SetOwnerEntity( owner );
  95. spot->Spawn();
  96.  
  97. // See if spot is valid
  98. trace_t tr;
  99. UTIL_TraceHull(
  100. org,
  101. org,
  102. mins,
  103. maxs,
  104. MASK_PLAYERSOLID,
  105. owner,
  106. COLLISION_GROUP_PLAYER_MOVEMENT,
  107. &tr );
  108.  
  109. validspot = !tr.startsolid;
  110.  
  111. if ( !validspot )
  112. {
  113. Vector org2 = org + Vector( 0, 0, 1 );
  114.  
  115. // See if spot is valid
  116. trace_t tr;
  117. UTIL_TraceHull(
  118. org2,
  119. org2,
  120. mins,
  121. maxs,
  122. MASK_PLAYERSOLID,
  123. owner,
  124. COLLISION_GROUP_PLAYER_MOVEMENT,
  125. &tr );
  126. validspot = !tr.startsolid;
  127. }
  128.  
  129. return spot;
  130. }
  131.  
  132. //-----------------------------------------------------------------------------
  133. // Purpose:
  134. //-----------------------------------------------------------------------------
  135. void CReservePlayerSpot::Spawn()
  136. {
  137. BaseClass::Spawn();
  138.  
  139. SetSolid( SOLID_BBOX );
  140. SetMoveType( MOVETYPE_NONE );
  141. // Make entity invisible
  142. AddEffects( EF_NODRAW );
  143. }
  144.  
  145. LINK_ENTITY_TO_CLASS( reserved_spot, CReservePlayerSpot );
  146.  
  147. #endif
  148. //-----------------------------------------------------------------------------
  149. // Purpose:
  150. // Input : mounting -
  151. // transit_speed -
  152. // goalpos -
  153. // *ladder -
  154. //-----------------------------------------------------------------------------
  155. void CHL2GameMovement::StartForcedMove( bool mounting, float transit_speed, const Vector& goalpos, CFuncLadder *ladder )
  156. {
  157. LadderMove_t* lm = GetLadderMove();
  158. Assert( lm );
  159. // Already active, just ignore
  160. if ( lm->m_bForceLadderMove )
  161. {
  162. return;
  163. }
  164.  
  165. #if !defined( CLIENT_DLL )
  166. if ( ladder )
  167. {
  168. ladder->PlayerGotOn( GetHL2Player() );
  169.  
  170. // If the Ladder only wants to be there for automount checking, abort now
  171. if ( ladder->DontGetOnLadder() )
  172. return;
  173. }
  174.  
  175. // Reserve goal slot here
  176. bool valid = false;
  177. lm->m_hReservedSpot = CReservePlayerSpot::ReserveSpot(
  178. player,
  179. goalpos,
  180. GetPlayerMins( ( player->GetFlags() & FL_DUCKING ) ? true : false ),
  181. GetPlayerMaxs( ( player->GetFlags() & FL_DUCKING ) ? true : false ),
  182. valid );
  183. if ( !valid )
  184. {
  185. // FIXME: Play a deny sound?
  186. if ( lm->m_hReservedSpot )
  187. {
  188. UTIL_Remove( lm->m_hReservedSpot );
  189. lm->m_hReservedSpot = NULL;
  190. }
  191. return;
  192. }
  193. #endif
  194.  
  195. // Use current player origin as start and new origin as dest
  196. lm->m_vecGoalPosition = goalpos;
  197. lm->m_vecStartPosition = mv->GetAbsOrigin();
  198.  
  199. // Figure out how long it will take to make the gap based on transit_speed
  200. Vector delta = lm->m_vecGoalPosition - lm->m_vecStartPosition;
  201.  
  202. float distance = delta.Length();
  203.  
  204. Assert( transit_speed > 0.001f );
  205.  
  206. // Compute time required to move that distance
  207. float transit_time = distance / transit_speed;
  208. if ( transit_time < 0.001f )
  209. {
  210. transit_time = 0.001f;
  211. }
  212.  
  213. lm->m_bForceLadderMove = true;
  214. lm->m_bForceMount = mounting;
  215.  
  216. lm->m_flStartTime = gpGlobals->curtime;
  217. lm->m_flArrivalTime = lm->m_flStartTime + transit_time;
  218.  
  219. lm->m_hForceLadder = ladder;
  220.  
  221. // Don't get stuck during this traversal since we'll just be slamming the player origin
  222. player->SetMoveType( MOVETYPE_NONE );
  223. player->SetMoveCollide( MOVECOLLIDE_DEFAULT );
  224. player->SetSolid( SOLID_NONE );
  225. SetLadder( ladder );
  226.  
  227. // Debounce the use key
  228. SwallowUseKey();
  229. }
  230.  
  231. //-----------------------------------------------------------------------------
  232. // Purpose: Returns false when finished
  233. //-----------------------------------------------------------------------------
  234. bool CHL2GameMovement::ContinueForcedMove()
  235. {
  236. LadderMove_t* lm = GetLadderMove();
  237. Assert( lm );
  238. Assert( lm->m_bForceLadderMove );
  239.  
  240. // Suppress regular motion
  241. mv->m_flForwardMove = 0.0f;
  242. mv->m_flSideMove = 0.0f;
  243. mv->m_flUpMove = 0.0f;
  244.  
  245. // How far along are we
  246. float frac = ( gpGlobals->curtime - lm->m_flStartTime ) / ( lm->m_flArrivalTime - lm->m_flStartTime );
  247. if ( frac > 1.0f )
  248. {
  249. lm->m_bForceLadderMove = false;
  250. #if !defined( CLIENT_DLL )
  251. // Remove "reservation entity"
  252. if ( lm->m_hReservedSpot )
  253. {
  254. UTIL_Remove( lm->m_hReservedSpot );
  255. lm->m_hReservedSpot = NULL;
  256. }
  257. #endif
  258. }
  259.  
  260. frac = clamp( frac, 0.0f, 1.0f );
  261.  
  262. // Move origin part of the way
  263. Vector delta = lm->m_vecGoalPosition - lm->m_vecStartPosition;
  264.  
  265. // Compute interpolated position
  266. Vector org;
  267. VectorMA( lm->m_vecStartPosition, frac, delta, org );
  268. mv->SetAbsOrigin( org );
  269.  
  270. // If finished moving, reset player to correct movetype (or put them on the ladder)
  271. if ( !lm->m_bForceLadderMove )
  272. {
  273. player->SetSolid( SOLID_BBOX );
  274. player->SetMoveType( MOVETYPE_WALK );
  275.  
  276. if ( lm->m_bForceMount && lm->m_hForceLadder != NULL )
  277. {
  278. player->SetMoveType( MOVETYPE_LADDER );
  279. SetLadder( lm->m_hForceLadder );
  280. }
  281.  
  282. // Zero out any velocity
  283. mv->m_vecVelocity.Init();
  284. }
  285.  
  286. // Stil active
  287. return lm->m_bForceLadderMove;
  288. }
  289.  
  290. // MY CODE Old Ladder
  291. //-----------------------------------------------------------------------------
  292. // Purpose: Returns true if the player is on a ladder
  293. // Input : &trace - ignored
  294. //-----------------------------------------------------------------------------
  295. bool CHL2GameMovement::OnLadder( trace_t &trace )
  296. //{
  297. // return ( GetLadder() != NULL ) ? true : false;
  298. //}
  299. {
  300. #if defined(HL2_DLL)
  301. if (GetLadder() == nullptr)
  302. return BaseClass::OnLadder(trace);
  303. else
  304. return true;
  305. #else
  306. return (GetLadder() != NULL) ? true : false;
  307. #endif
  308. }
  309.  
  310. //-----------------------------------------------------------------------------
  311. // Purpose:
  312. // Input : ladders -
  313. // maxdist -
  314. // **ppLadder -
  315. // ladderOrigin -
  316. //-----------------------------------------------------------------------------
  317. void CHL2GameMovement::Findladder( float maxdist, CFuncLadder **ppLadder, Vector& ladderOrigin, const CFuncLadder *skipLadder )
  318. {
  319. CFuncLadder *bestLadder = NULL;
  320. float bestDist = MAX_COORD_INTEGER;
  321. Vector bestOrigin;
  322.  
  323. bestOrigin.Init();
  324.  
  325. float maxdistSqr = maxdist * maxdist;
  326.  
  327.  
  328. int c = CFuncLadder::GetLadderCount();
  329. for ( int i = 0 ; i < c; i++ )
  330. {
  331. CFuncLadder *ladder = CFuncLadder::GetLadder( i );
  332.  
  333. if ( !ladder->IsEnabled() )
  334. continue;
  335.  
  336. if ( skipLadder && ladder == skipLadder )
  337. continue;
  338.  
  339. Vector topPosition;
  340. Vector bottomPosition;
  341.  
  342. ladder->GetTopPosition( topPosition );
  343. ladder->GetBottomPosition( bottomPosition );
  344.  
  345. Vector closest;
  346. CalcClosestPointOnLineSegment( mv->GetAbsOrigin(), bottomPosition, topPosition, closest, NULL );
  347.  
  348. float distSqr = ( closest - mv->GetAbsOrigin() ).LengthSqr();
  349.  
  350. // Too far away
  351. if ( distSqr > maxdistSqr )
  352. {
  353. continue;
  354. }
  355.  
  356. // Need to trace to see if it's clear
  357. trace_t tr;
  358.  
  359. UTIL_TraceLine( mv->GetAbsOrigin(), closest,
  360. MASK_PLAYERSOLID,
  361. player,
  362. COLLISION_GROUP_NONE,
  363. &tr );
  364.  
  365. if ( tr.fraction != 1.0f &&
  366. tr.m_pEnt &&
  367. tr.m_pEnt != ladder )
  368. {
  369. // Try a trace stepped up from the ground a bit, in case there's something at ground level blocking us.
  370. float sizez = GetPlayerMaxs().z - GetPlayerMins().z;
  371.  
  372. UTIL_TraceLine( mv->GetAbsOrigin() + Vector( 0, 0, sizez * 0.5f ), closest,
  373. MASK_PLAYERSOLID,
  374. player,
  375. COLLISION_GROUP_NONE,
  376. &tr );
  377.  
  378. if ( tr.fraction != 1.0f &&
  379. tr.m_pEnt &&
  380. tr.m_pEnt != ladder &&
  381. !tr.m_pEnt->IsSolidFlagSet( FSOLID_TRIGGER ) )
  382. {
  383. continue;
  384. }
  385. }
  386.  
  387. // See if this is the best one so far
  388. if ( distSqr < bestDist )
  389. {
  390. bestDist = distSqr;
  391. bestLadder = ladder;
  392. bestOrigin = closest;
  393. }
  394. }
  395.  
  396. // Return best ladder spot
  397. *ppLadder = bestLadder;
  398. ladderOrigin = bestOrigin;
  399.  
  400. }
  401.  
  402. static bool NearbyDismountLessFunc( const NearbyDismount_t& lhs, const NearbyDismount_t& rhs )
  403. {
  404. return lhs.distSqr < rhs.distSqr;
  405. }
  406.  
  407. void CHL2GameMovement::GetSortedDismountNodeList( const Vector &org, float radius, CFuncLadder *ladder, CUtlRBTree< NearbyDismount_t, int >& list )
  408. {
  409. float radiusSqr = radius * radius;
  410.  
  411. int i;
  412. int c = ladder->GetDismountCount();
  413. for ( i = 0; i < c; i++ )
  414. {
  415. CInfoLadderDismount *spot = ladder->GetDismount( i );
  416. if ( !spot )
  417. continue;
  418.  
  419. float distSqr = ( spot->GetAbsOrigin() - org ).LengthSqr();
  420. if ( distSqr > radiusSqr )
  421. continue;
  422.  
  423. NearbyDismount_t nd;
  424. nd.dismount = spot;
  425. nd.distSqr = distSqr;
  426.  
  427. list.Insert( nd );
  428. }
  429. }
  430.  
  431. //-----------------------------------------------------------------------------
  432. // Purpose:
  433. // *ladder -
  434. // Output : Returns true on success, false on failure.
  435. //-----------------------------------------------------------------------------
  436. bool CHL2GameMovement::ExitLadderViaDismountNode( CFuncLadder *ladder, bool strict, bool useAlternate )
  437. {
  438. // Find the best ladder exit node
  439. float bestDot = -99999.0f;
  440. float bestDistance = 99999.0f;
  441. Vector bestDest;
  442. bool found = false;
  443.  
  444. // For 'alternate' dismount
  445. bool foundAlternate = false;
  446. Vector alternateDest;
  447. float alternateDist = 99999.0f;
  448.  
  449. CUtlRBTree< NearbyDismount_t, int > nearbyDismounts( 0, 0, NearbyDismountLessFunc );
  450.  
  451. GetSortedDismountNodeList( mv->GetAbsOrigin(), 100.0f, ladder, nearbyDismounts );
  452.  
  453. int i;
  454.  
  455. for ( i = nearbyDismounts.FirstInorder(); i != nearbyDismounts.InvalidIndex() ; i = nearbyDismounts.NextInorder( i ) )
  456. {
  457. CInfoLadderDismount *spot = nearbyDismounts[ i ].dismount;
  458. if ( !spot )
  459. {
  460. Assert( !"What happened to the spot!!!" );
  461. continue;
  462. }
  463.  
  464. // See if it's valid to put the player there...
  465. Vector org = spot->GetAbsOrigin() + Vector( 0, 0, 1 );
  466.  
  467. trace_t tr;
  468. UTIL_TraceHull(
  469. org,
  470. org,
  471. GetPlayerMins( ( player->GetFlags() & FL_DUCKING ) ? true : false ),
  472. GetPlayerMaxs( ( player->GetFlags() & FL_DUCKING ) ? true : false ),
  473. MASK_PLAYERSOLID,
  474. player,
  475. COLLISION_GROUP_PLAYER_MOVEMENT,
  476. &tr );
  477.  
  478. // Nope...
  479. if ( tr.startsolid )
  480. {
  481. continue;
  482. }
  483.  
  484. // Find the best dot product
  485. Vector vecToSpot = org - ( mv->GetAbsOrigin() + player->GetViewOffset() );
  486. vecToSpot.z = 0.0f;
  487. float d = VectorNormalize( vecToSpot );
  488.  
  489. float dot = vecToSpot.Dot( m_vecForward );
  490.  
  491. // We're not facing at it...ignore
  492. if ( dot < 0.5f )
  493. {
  494. if( useAlternate && d < alternateDist )
  495. {
  496. alternateDest = org;
  497. alternateDist = d;
  498. foundAlternate = true;
  499. }
  500.  
  501. continue;
  502. }
  503.  
  504. if ( dot > bestDot )
  505. {
  506. bestDest = org;
  507. bestDistance = d;
  508. bestDot = dot;
  509. found = true;
  510. }
  511. }
  512.  
  513. if ( found )
  514. {
  515. // Require a more specific
  516. if ( strict &&
  517. ( ( bestDot < 0.7f ) || ( bestDistance > 40.0f ) ) )
  518. {
  519. return false;
  520. }
  521.  
  522. StartForcedMove( false, player->MaxSpeed(), bestDest, NULL );
  523. return true;
  524. }
  525.  
  526. if( useAlternate )
  527. {
  528. // Desperate. Don't refuse to let a person off of a ladder if it can be helped. Use the
  529. // alternate dismount if there is one.
  530. if( foundAlternate && alternateDist <= 60.0f )
  531. {
  532. StartForcedMove( false, player->MaxSpeed(), alternateDest, NULL );
  533. return true;
  534. }
  535. }
  536.  
  537. return false;
  538. }
  539.  
  540. //-----------------------------------------------------------------------------
  541. // Purpose:
  542. // Input : bOnLadder -
  543. //-----------------------------------------------------------------------------
  544. void CHL2GameMovement::FullLadderMove()
  545. {
  546. // MY CODE Old Ladder
  547. #if defined(HL2_DLL)
  548. if (GetLadder() == nullptr)
  549. {
  550. BaseClass::FullLadderMove();
  551. return;
  552. }
  553. #endif
  554. ////////////////////////
  555. #if !defined( CLIENT_DLL )
  556. CFuncLadder *ladder = GetLadder();
  557. Assert( ladder );
  558. if ( !ladder )
  559. {
  560. return;
  561. }
  562.  
  563. CheckWater();
  564.  
  565. // Was jump button pressed? If so, don't do anything here
  566. if ( mv->m_nButtons & IN_JUMP )
  567. {
  568. CheckJumpButton();
  569. return;
  570. }
  571. else
  572. {
  573. mv->m_nOldButtons &= ~IN_JUMP;
  574. }
  575.  
  576. player->SetGroundEntity( NULL );
  577.  
  578. // Remember old positions in case we cancel this movement
  579. Vector oldVelocity = mv->m_vecVelocity;
  580. Vector oldOrigin = mv->GetAbsOrigin();
  581.  
  582. Vector topPosition;
  583. Vector bottomPosition;
  584.  
  585. ladder->GetTopPosition( topPosition );
  586. ladder->GetBottomPosition( bottomPosition );
  587.  
  588. // Compute parametric distance along ladder vector...
  589. float oldt;
  590. CalcDistanceSqrToLine( mv->GetAbsOrigin(), topPosition, bottomPosition, &oldt );
  591.  
  592. // Perform the move accounting for any base velocity.
  593. VectorAdd (mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity);
  594. TryPlayerMove();
  595. VectorSubtract (mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity);
  596.  
  597. // Pressed buttons are "changed(xor)" and'ed with the mask of currently held buttons
  598. int buttonsChanged = ( mv->m_nOldButtons ^ mv->m_nButtons ); // These buttons have changed this frame
  599. int buttonsPressed = buttonsChanged & mv->m_nButtons;
  600. bool pressed_use = ( buttonsPressed & IN_USE ) ? true : false;
  601. bool pressing_forward_or_side = mv->m_flForwardMove != 0.0f || mv->m_flSideMove != 0.0f;
  602.  
  603. Vector ladderVec = topPosition - bottomPosition;
  604. float LadderLength = VectorNormalize( ladderVec );
  605. // This test is not perfect by any means, but should help a bit
  606. bool moving_along_ladder = false;
  607. if ( pressing_forward_or_side )
  608. {
  609. float fwdDot = m_vecForward.Dot( ladderVec );
  610. if ( fabs( fwdDot ) > 0.9f )
  611. {
  612. moving_along_ladder = true;
  613. }
  614. }
  615.  
  616. // Compute parametric distance along ladder vector...
  617. float newt;
  618. CalcDistanceSqrToLine( mv->GetAbsOrigin(), topPosition, bottomPosition, &newt );
  619.  
  620. // Fudge of 2 units
  621. float tolerance = 1.0f / LadderLength;
  622.  
  623. bool wouldleaveladder = false;
  624. // Moving pPast top or bottom?
  625. if ( newt < -tolerance )
  626. {
  627. wouldleaveladder = newt < oldt;
  628. }
  629. else if ( newt > ( 1.0f + tolerance ) )
  630. {
  631. wouldleaveladder = newt > oldt;
  632. }
  633.  
  634. // See if we are near the top or bottom but not moving
  635. float dist1sqr, dist2sqr;
  636.  
  637. dist1sqr = ( topPosition - mv->GetAbsOrigin() ).LengthSqr();
  638. dist2sqr = ( bottomPosition - mv->GetAbsOrigin() ).LengthSqr();
  639.  
  640. float dist = MIN( dist1sqr, dist2sqr );
  641. bool neardismountnode = ( dist < 16.0f * 16.0f ) ? true : false;
  642. float ladderUnitsPerTick = ( MAX_CLIMB_SPEED * gpGlobals->interval_per_tick );
  643. bool neardismountnode2 = ( dist < ladderUnitsPerTick * ladderUnitsPerTick ) ? true : false;
  644.  
  645. // Really close to node, cvar is set, and pressing a key, then simulate a +USE
  646. bool auto_dismount_use = ( neardismountnode2 &&
  647. sv_autoladderdismount.GetBool() &&
  648. pressing_forward_or_side &&
  649. !moving_along_ladder );
  650.  
  651. bool fully_underwater = ( player->GetWaterLevel() == WL_Eyes ) ? true : false;
  652.  
  653. // If the user manually pressed use or we're simulating it, then use_dismount will occur
  654. bool use_dismount = pressed_use || auto_dismount_use;
  655.  
  656. if ( fully_underwater && !use_dismount )
  657. {
  658. // If fully underwater, we require looking directly at a dismount node
  659. /// to "float off" a ladder mid way...
  660. if ( ExitLadderViaDismountNode( ladder, true ) )
  661. {
  662. // See if they +used a dismount point mid-span..
  663. return;
  664. }
  665. }
  666.  
  667. // If the movement would leave the ladder and they're not automated or pressing use, disallow the movement
  668. if ( !use_dismount )
  669. {
  670. if ( wouldleaveladder )
  671. {
  672. // Don't let them leave the ladder if they were on it
  673. mv->m_vecVelocity = oldVelocity;
  674. mv->SetAbsOrigin( oldOrigin );
  675. }
  676. return;
  677. }
  678.  
  679. // If the move would not leave the ladder and we're near close to the end, then just accept the move
  680. if ( !wouldleaveladder && !neardismountnode )
  681. {
  682. // Otherwise, if the move would leave the ladder, disallow it.
  683. if ( pressed_use )
  684. {
  685. if ( ExitLadderViaDismountNode( ladder, false, IsX360() ) )
  686. {
  687. // See if they +used a dismount point mid-span..
  688. return;
  689. }
  690.  
  691. player->SetMoveType( MOVETYPE_WALK );
  692. player->SetMoveCollide( MOVECOLLIDE_DEFAULT );
  693. SetLadder( NULL );
  694. GetHL2Player()->m_bPlayUseDenySound = false;
  695.  
  696. // Dismount with a bit of velocity in facing direction
  697. VectorScale( m_vecForward, USE_DISMOUNT_SPEED, mv->m_vecVelocity );
  698. mv->m_vecVelocity.z = 50;
  699. }
  700. return;
  701. }
  702.  
  703. // Debounce the use key
  704. if ( pressed_use )
  705. {
  706. SwallowUseKey();
  707. }
  708.  
  709. // Try auto exit, if possible
  710. if ( ExitLadderViaDismountNode( ladder, false, pressed_use ) )
  711. {
  712. return;
  713. }
  714.  
  715. if ( wouldleaveladder )
  716. {
  717. // Otherwise, if the move would leave the ladder, disallow it.
  718. if ( pressed_use )
  719. {
  720. player->SetMoveType( MOVETYPE_WALK );
  721. player->SetMoveCollide( MOVECOLLIDE_DEFAULT );
  722. SetLadder( NULL );
  723.  
  724. // Dismount with a bit of velocity in facing direction
  725. VectorScale( m_vecForward, USE_DISMOUNT_SPEED, mv->m_vecVelocity );
  726. mv->m_vecVelocity.z = 50;
  727. }
  728. else
  729. {
  730. mv->m_vecVelocity = oldVelocity;
  731. mv->SetAbsOrigin( oldOrigin );
  732. }
  733. }
  734. #endif
  735. }
  736.  
  737. bool CHL2GameMovement::CheckLadderAutoMountEndPoint( CFuncLadder *ladder, const Vector& bestOrigin )
  738. {
  739. // See if we're really near an endpoint
  740. if ( !ladder )
  741. return false;
  742.  
  743. Vector top, bottom;
  744. ladder->GetTopPosition( top );
  745. ladder->GetBottomPosition( bottom );
  746.  
  747. float d1, d2;
  748.  
  749. d1 = ( top - mv->GetAbsOrigin() ).LengthSqr();
  750. d2 = ( bottom - mv->GetAbsOrigin() ).LengthSqr();
  751.  
  752. if ( d1 > 16 * 16 && d2 > 16 * 16 )
  753. return false;
  754.  
  755. Vector ladderAxis;
  756.  
  757. if ( d1 < 16 * 16 )
  758. {
  759. // Close to top
  760. ladderAxis = bottom - top;
  761. }
  762. else
  763. {
  764. ladderAxis = top - bottom;
  765. }
  766.  
  767. VectorNormalize( ladderAxis );
  768.  
  769. if ( ladderAxis.Dot( m_vecForward ) > sv_ladderautomountdot.GetFloat() )
  770. {
  771. StartForcedMove( true, player->MaxSpeed(), bestOrigin, ladder );
  772. return true;
  773. }
  774.  
  775. return false;
  776. }
  777.  
  778. bool CHL2GameMovement::CheckLadderAutoMountCone( CFuncLadder *ladder, const Vector& bestOrigin, float maxAngleDelta, float maxDistToLadder )
  779. {
  780. // Never 'back' onto ladders or stafe onto ladders
  781. if ( ladder != NULL &&
  782. ( mv->m_flForwardMove > 0.0f ) )
  783. {
  784. Vector top, bottom;
  785. ladder->GetTopPosition( top );
  786. ladder->GetBottomPosition( bottom );
  787.  
  788. Vector ladderAxis = top - bottom;
  789. VectorNormalize( ladderAxis );
  790.  
  791. Vector probe = mv->GetAbsOrigin();
  792.  
  793. Vector closest;
  794. CalcClosestPointOnLineSegment( probe, bottom, top, closest, NULL );
  795.  
  796. Vector vecToLadder = closest - probe;
  797.  
  798. float dist = VectorNormalize( vecToLadder );
  799.  
  800. Vector flatLadder = vecToLadder;
  801. flatLadder.z = 0.0f;
  802. Vector flatForward = m_vecForward;
  803. flatForward.z = 0.0f;
  804.  
  805. VectorNormalize( flatLadder );
  806. VectorNormalize( flatForward );
  807.  
  808. float facingDot = flatForward.Dot( flatLadder );
  809. float angle = acos( facingDot ) * 180 / M_PI;
  810.  
  811. bool closetoladder = ( dist != 0.0f && dist < maxDistToLadder ) ? true : false;
  812. bool reallyclosetoladder = ( dist != 0.0f && dist < 4.0f ) ? true : false;
  813.  
  814. bool facingladderaxis = ( angle < maxAngleDelta ) ? true : false;
  815. bool facingalongaxis = ( (float)fabs( ladderAxis.Dot( m_vecForward ) ) > sv_ladderautomountdot.GetFloat() ) ? true : false;
  816. #if 0
  817. Msg( "close %i length %.3f maxdist %.3f facing %.3f dot %.3f ang %.3f\n",
  818. closetoladder ? 1 : 0,
  819. dist,
  820. maxDistToLadder,
  821. (float)fabs( ladderAxis.Dot( m_vecForward ) ),
  822. facingDot,
  823. angle);
  824. #endif
  825.  
  826. // Tracker 21776: Don't mount ladders this way if strafing
  827. bool strafing = ( fabs( mv->m_flSideMove ) < 1.0f ) ? false : true;
  828.  
  829. if ( ( ( facingDot > 0.0f && !strafing ) || facingalongaxis ) &&
  830. ( facingladderaxis || reallyclosetoladder ) &&
  831. closetoladder )
  832. {
  833. StartForcedMove( true, player->MaxSpeed(), bestOrigin, ladder );
  834. return true;
  835. }
  836. }
  837.  
  838. return false;
  839. }
  840.  
  841. //-----------------------------------------------------------------------------
  842. // Purpose: Must be facing toward ladder
  843. // Input : *ladder -
  844. // Output : Returns true on success, false on failure.
  845. //-----------------------------------------------------------------------------
  846. bool CHL2GameMovement::LookingAtLadder( CFuncLadder *ladder )
  847. {
  848. if ( !ladder )
  849. {
  850. return false;
  851. }
  852.  
  853. // Get ladder end points
  854. Vector top, bottom;
  855. ladder->GetTopPosition( top );
  856. ladder->GetBottomPosition( bottom );
  857.  
  858. // Find closest point on ladder to player (could be an endpoint)
  859. Vector closest;
  860. CalcClosestPointOnLineSegment( mv->GetAbsOrigin(), bottom, top, closest, NULL );
  861.  
  862. // Flatten our view direction to 2D
  863. Vector flatForward = m_vecForward;
  864. flatForward.z = 0.0f;
  865.  
  866. // Because the ladder itself is not a solid, the player's origin may actually be
  867. // permitted to pass it, and that will screw up our dot product.
  868. // So back up the player's origin a bit to do the facing calculation.
  869. Vector vecAdjustedOrigin = mv->GetAbsOrigin() - 8.0f * flatForward;
  870.  
  871. // Figure out vector from player to closest point on ladder
  872. Vector vecToLadder = closest - vecAdjustedOrigin;
  873.  
  874. // Flatten it to 2D
  875. Vector flatLadder = vecToLadder;
  876. flatLadder.z = 0.0f;
  877.  
  878. // Normalize the vectors (unnecessary)
  879. VectorNormalize( flatLadder );
  880. VectorNormalize( flatForward );
  881.  
  882. // Compute dot product to see if forward is in same direction as vec to ladder
  883. float facingDot = flatForward.Dot( flatLadder );
  884.  
  885. float requiredDot = ( sv_ladder_useonly.GetBool() ) ? -0.99 : 0.0;
  886.  
  887. // Facing same direction if dot > = requiredDot...
  888. bool facingladder = ( facingDot >= requiredDot );
  889.  
  890. return facingladder;
  891. }
  892.  
  893. //-----------------------------------------------------------------------------
  894. // Purpose:
  895. // Input : &trace -
  896. //-----------------------------------------------------------------------------
  897. bool CHL2GameMovement::CheckLadderAutoMount( CFuncLadder *ladder, const Vector& bestOrigin )
  898. {
  899. #if !defined( CLIENT_DLL )
  900.  
  901. if ( ladder != NULL )
  902. {
  903. StartForcedMove( true, player->MaxSpeed(), bestOrigin, ladder );
  904. return true;
  905. }
  906.  
  907. #endif
  908. return false;
  909. }
  910.  
  911. //-----------------------------------------------------------------------------
  912. // Purpose:
  913. //-----------------------------------------------------------------------------
  914. bool CHL2GameMovement::LadderMove( void )
  915. {
  916.  
  917. if ( player->GetMoveType() == MOVETYPE_NOCLIP )
  918. {
  919. SetLadder( NULL );
  920. //return false;
  921. // MY CODE Old Ladder
  922. #if defined(HL2_DLL)
  923. return BaseClass::LadderMove();
  924. #else
  925. return false;
  926. #endif
  927. /////////////////
  928. }
  929.  
  930. // If being forced to mount/dismount continue to act like we are on the ladder
  931. if ( IsForceMoveActive() && ContinueForcedMove() )
  932. {
  933. return true;
  934. }
  935.  
  936. CFuncLadder *bestLadder = NULL;
  937. Vector bestOrigin( 0, 0, 0 );
  938.  
  939. CFuncLadder *ladder = GetLadder();
  940.  
  941. // Something 1) deactivated the ladder... or 2) something external applied
  942. // a force to us. In either case make the player fall, etc.
  943. if ( ladder &&
  944. ( !ladder->IsEnabled() ||
  945. ( player->GetBaseVelocity().LengthSqr() > 1.0f ) ) )
  946. {
  947. GetHL2Player()->ExitLadder();
  948. ladder = NULL;
  949. }
  950.  
  951. if ( !ladder )
  952. {
  953. Findladder( 64.0f, &bestLadder, bestOrigin, NULL );
  954. }
  955.  
  956. #if !defined (CLIENT_DLL)
  957. if( !ladder && bestLadder && sv_ladder_useonly.GetBool() )
  958. {
  959. GetHL2Player()->DisplayLadderHudHint();
  960. }
  961. #endif
  962.  
  963. int buttonsChanged = ( mv->m_nOldButtons ^ mv->m_nButtons ); // These buttons have changed this frame
  964. int buttonsPressed = buttonsChanged & mv->m_nButtons;
  965. bool pressed_use = ( buttonsPressed & IN_USE ) ? true : false;
  966.  
  967. // If I'm already moving on a ladder, use the previous ladder direction
  968. if ( !ladder && !pressed_use )
  969. {
  970. // If flying through air, allow mounting ladders if we are facing < 15 degress from the ladder and we are close
  971. if ( !ladder && !sv_ladder_useonly.GetBool() )
  972. {
  973. // Tracker 6625: Don't need to be leaping to auto mount using this method...
  974. // But if we are on the ground, then we must not be backing into the ladder (Tracker 12961)
  975. bool onground = player->GetGroundEntity() ? true : false;
  976. if ( !onground || ( mv->m_flForwardMove > 0.0f ) )
  977. {
  978. if ( CheckLadderAutoMountCone( bestLadder, bestOrigin, 15.0f, 32.0f ) )
  979. {
  980. return true;
  981. }
  982. }
  983.  
  984. // Pressing forward while looking at ladder and standing (or floating) near a mounting point
  985. if ( mv->m_flForwardMove > 0.0f )
  986. {
  987. if ( CheckLadderAutoMountEndPoint( bestLadder, bestOrigin ) )
  988. {
  989. return true;
  990. }
  991. }
  992. }
  993.  
  994. //return false;
  995. // MY CODE Old Ladder
  996. #if defined(HL2_DLL)
  997. return BaseClass::LadderMove();
  998. #else
  999. return false;
  1000. #endif
  1001. ////////////////
  1002. }
  1003.  
  1004. if ( !ladder &&
  1005. LookingAtLadder( bestLadder ) &&
  1006. CheckLadderAutoMount( bestLadder, bestOrigin ) )
  1007. {
  1008. return true;
  1009. }
  1010.  
  1011. // Reassign the ladder
  1012. ladder = GetLadder();
  1013. if ( !ladder )
  1014. {
  1015. //return false;
  1016. // MY CODE Old Ladder
  1017. #if defined(HL2_DLL)
  1018. return BaseClass::LadderMove();
  1019. #else
  1020. return false;
  1021. #endif
  1022. ////////////////
  1023. }
  1024.  
  1025. // Don't play the deny sound
  1026. if ( pressed_use )
  1027. {
  1028. GetHL2Player()->m_bPlayUseDenySound = false;
  1029. }
  1030.  
  1031. // Make sure we are on the ladder
  1032. player->SetMoveType( MOVETYPE_LADDER );
  1033. player->SetMoveCollide( MOVECOLLIDE_DEFAULT );
  1034.  
  1035. player->SetGravity( 0.0f );
  1036.  
  1037. float forwardSpeed = 0.0f;
  1038. float rightSpeed = 0.0f;
  1039.  
  1040. float speed = player->MaxSpeed();
  1041.  
  1042.  
  1043. if ( mv->m_nButtons & IN_BACK )
  1044. {
  1045. forwardSpeed -= speed;
  1046. }
  1047.  
  1048. if ( mv->m_nButtons & IN_FORWARD )
  1049. {
  1050. forwardSpeed += speed;
  1051. }
  1052.  
  1053. if ( mv->m_nButtons & IN_MOVELEFT )
  1054. {
  1055. rightSpeed -= speed;
  1056. }
  1057.  
  1058. if ( mv->m_nButtons & IN_MOVERIGHT )
  1059. {
  1060. rightSpeed += speed;
  1061. }
  1062.  
  1063. if ( mv->m_nButtons & IN_JUMP )
  1064. {
  1065. player->SetMoveType( MOVETYPE_WALK );
  1066. // Remove from ladder
  1067. SetLadder( NULL );
  1068.  
  1069. // Jump in view direction
  1070. Vector jumpDir = m_vecForward;
  1071.  
  1072. // unless pressing backward or something like that
  1073. if ( mv->m_flForwardMove < 0.0f )
  1074. {
  1075. jumpDir = -jumpDir;
  1076. }
  1077.  
  1078. VectorNormalize( jumpDir );
  1079.  
  1080. VectorScale( jumpDir, MAX_CLIMB_SPEED, mv->m_vecVelocity );
  1081. // Tracker 13558: Don't add any extra z velocity if facing downward at all
  1082. if ( m_vecForward.z >= 0.0f )
  1083. {
  1084. mv->m_vecVelocity.z = mv->m_vecVelocity.z + 50;
  1085. }
  1086. //return false;
  1087. // MY CODE Old Ladder
  1088. #if defined(HL2_DLL)
  1089. return BaseClass::LadderMove();
  1090. #else
  1091. return false;
  1092. #endif
  1093. ////////////////
  1094. }
  1095.  
  1096. if ( forwardSpeed != 0 || rightSpeed != 0 )
  1097. {
  1098. // See if the player is looking toward the top or the bottom
  1099. Vector velocity;
  1100.  
  1101. VectorScale( m_vecForward, forwardSpeed, velocity );
  1102. VectorMA( velocity, rightSpeed, m_vecRight, velocity );
  1103.  
  1104. VectorNormalize( velocity );
  1105.  
  1106. Vector ladderUp;
  1107. ladder->ComputeLadderDir( ladderUp );
  1108. VectorNormalize( ladderUp );
  1109.  
  1110. Vector topPosition;
  1111. Vector bottomPosition;
  1112.  
  1113. ladder->GetTopPosition( topPosition );
  1114. ladder->GetBottomPosition( bottomPosition );
  1115.  
  1116. // Check to see if we've mounted the ladder in a bogus spot and, if so, just fall off the ladder...
  1117. float dummyt = 0.0f;
  1118. float distFromLadderSqr = CalcDistanceSqrToLine( mv->GetAbsOrigin(), topPosition, bottomPosition, &dummyt );
  1119. if ( distFromLadderSqr > 36.0f )
  1120. {
  1121. // Uh oh, we fell off zee ladder...
  1122. player->SetMoveType( MOVETYPE_WALK );
  1123. // Remove from ladder
  1124. SetLadder( NULL );
  1125. //return false;
  1126. // MY CODE Old Ladder
  1127. #if defined(HL2_DLL)
  1128. return BaseClass::LadderMove();
  1129. #else
  1130. return false;
  1131. #endif
  1132. ///////////////
  1133. }
  1134.  
  1135. bool ishorizontal = fabs( topPosition.z - bottomPosition.z ) < 64.0f ? true : false;
  1136.  
  1137. float changeover = ishorizontal ? 0.0f : 0.3f;
  1138.  
  1139. float factor = 1.0f;
  1140. if ( velocity.z >= 0 )
  1141. {
  1142. float dotTop = ladderUp.Dot( velocity );
  1143. if ( dotTop < -changeover )
  1144. {
  1145. // Aimed at bottom
  1146. factor = -1.0f;
  1147. }
  1148. }
  1149. else
  1150. {
  1151. float dotBottom = -ladderUp.Dot( velocity );
  1152. if ( dotBottom > changeover )
  1153. {
  1154. factor = -1.0f;
  1155. }
  1156. }
  1157.  
  1158. #ifdef _XBOX
  1159. if( sv_ladders_useonly.GetBool() )
  1160. {
  1161. // Stick up climbs up, stick down climbs down. No matter which way you're looking.
  1162. if ( mv->m_nButtons & IN_FORWARD )
  1163. {
  1164. factor = 1.0f;
  1165. }
  1166. else if( mv->m_nButtons & IN_BACK )
  1167. {
  1168. factor = -1.0f;
  1169. }
  1170. }
  1171. #endif//_XBOX
  1172.  
  1173. mv->m_vecVelocity = MAX_CLIMB_SPEED * factor * ladderUp;
  1174. }
  1175. else
  1176. {
  1177. mv->m_vecVelocity.Init();
  1178. }
  1179.  
  1180. return true;
  1181. }
  1182.  
  1183. void CHL2GameMovement::SetGroundEntity( trace_t *pm )
  1184. {
  1185. CBaseEntity *newGround = pm ? pm->m_pEnt : NULL;
  1186.  
  1187. //Adrian: Special case for combine balls.
  1188. if ( newGround && newGround->GetCollisionGroup() == HL2COLLISION_GROUP_COMBINE_BALL_NPC )
  1189. {
  1190. return;
  1191. }
  1192.  
  1193. BaseClass::SetGroundEntity( pm );
  1194. }
  1195.  
  1196. bool CHL2GameMovement::CanAccelerate()
  1197. {
  1198. #ifdef HL2MP
  1199. if ( player->IsObserver() )
  1200. {
  1201. return true;
  1202. }
  1203. #endif
  1204.  
  1205. BaseClass::CanAccelerate();
  1206.  
  1207. return true;
  1208. }
  1209.  
  1210.  
  1211. #ifndef PORTAL // Portal inherits from this but needs to declare it's own global interface
  1212. // Expose our interface.
  1213. static CHL2GameMovement g_GameMovement;
  1214. IGameMovement *g_pGameMovement = ( IGameMovement * )&g_GameMovement;
  1215.  
  1216. EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CGameMovement, IGameMovement,INTERFACENAME_GAMEMOVEMENT, g_GameMovement );
  1217. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement