summaryrefslogtreecommitdiff
path: root/game/server/pushentity.h
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/pushentity.h')
-rw-r--r--game/server/pushentity.h160
1 files changed, 160 insertions, 0 deletions
diff --git a/game/server/pushentity.h b/game/server/pushentity.h
new file mode 100644
index 0000000..f1c02d3
--- /dev/null
+++ b/game/server/pushentity.h
@@ -0,0 +1,160 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+#ifndef PUSHENTITY_H
+#define PUSHENTITY_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "movetype_push.h"
+
+//-----------------------------------------------------------------------------
+// Purpose: Keeps track of original positions of any entities that are being possibly pushed
+// and handles restoring positions for those objects if the push is aborted
+//-----------------------------------------------------------------------------
+class CPhysicsPushedEntities
+{
+public:
+
+ DECLARE_CLASS_NOBASE( CPhysicsPushedEntities );
+
+ CPhysicsPushedEntities( void );
+
+ // Purpose: Tries to rotate an entity hierarchy, returns the blocker if any
+ CBaseEntity *PerformRotatePush( CBaseEntity *pRoot, float movetime );
+
+ // Purpose: Tries to linearly push an entity hierarchy, returns the blocker if any
+ CBaseEntity *PerformLinearPush( CBaseEntity *pRoot, float movetime );
+
+ int CountMovedEntities() { return m_rgMoved.Count(); }
+ void StoreMovedEntities( physicspushlist_t &list );
+ void BeginPush( CBaseEntity *pRootEntity );
+
+protected:
+
+ // describes the per-frame incremental motion of a rotating MOVETYPE_PUSH
+ struct RotatingPushMove_t
+ {
+ Vector origin;
+ matrix3x4_t startLocalToWorld;
+ matrix3x4_t endLocalToWorld;
+ QAngle amove; // delta orientation
+ };
+
+ // Pushers + their original positions also (for touching triggers)
+ struct PhysicsPusherInfo_t
+ {
+ CBaseEntity *m_pEntity;
+ Vector m_vecStartAbsOrigin;
+ };
+
+ // Pushed entities + various state related to them being pushed
+ struct PhysicsPushedInfo_t
+ {
+ CBaseEntity *m_pEntity;
+ Vector m_vecStartAbsOrigin;
+ trace_t m_Trace;
+ bool m_bBlocked;
+ bool m_bPusherIsGround;
+ };
+
+ // Adds the specified entity to the list
+ void AddEntity( CBaseEntity *ent );
+
+ // If a move fails, restores all entities to their original positions
+ void RestoreEntities( );
+
+ // Compute the direction to move the rotation blocker
+ void ComputeRotationalPushDirection( CBaseEntity *pBlocker, const RotatingPushMove_t &rotPushMove, Vector *pMove, CBaseEntity *pRoot );
+
+ // Speculatively checks to see if all entities in this list can be pushed
+ bool SpeculativelyCheckPush( PhysicsPushedInfo_t &info, const Vector &vecAbsPush, bool bRotationalPush );
+
+ // Speculatively checks to see if all entities in this list can be pushed
+ virtual bool SpeculativelyCheckRotPush( const RotatingPushMove_t &rotPushMove, CBaseEntity *pRoot );
+
+ // Speculatively checks to see if all entities in this list can be pushed
+ virtual bool SpeculativelyCheckLinearPush( const Vector &vecAbsPush );
+
+ // Registers a blockage
+ CBaseEntity *RegisterBlockage();
+
+ // Some fixup for objects pushed by rotating objects
+ virtual void FinishRotPushedEntity( CBaseEntity *pPushedEntity, const RotatingPushMove_t &rotPushMove );
+
+ // Commits the speculative movement
+ void FinishPush( bool bIsRotPush = false, const RotatingPushMove_t *pRotPushMove = NULL );
+
+ // Generates a list of all entities potentially blocking all pushers
+ void GenerateBlockingEntityList();
+ void GenerateBlockingEntityListAddBox( const Vector &vecMoved );
+
+ // Purpose: Gets a list of all entities hierarchically attached to the root
+ void SetupAllInHierarchy( CBaseEntity *pParent );
+
+ // Unlink + relink the pusher list so we can actually do the push
+ void UnlinkPusherList( int *pPusherHandles );
+ void RelinkPusherList( int *pPusherHandles );
+
+ // Causes all entities in the list to touch triggers from their prev position
+ void FinishPushers();
+
+ // Purpose: Rotates the root entity, fills in the pushmove structure
+ void RotateRootEntity( CBaseEntity *pRoot, float movetime, RotatingPushMove_t &rotation );
+
+ // Purpose: Linearly moves the root entity
+ void LinearlyMoveRootEntity( CBaseEntity *pRoot, float movetime, Vector *pAbsPushVector );
+
+ bool IsPushedPositionValid( CBaseEntity *pBlocker );
+
+protected:
+
+ CUtlVector<PhysicsPusherInfo_t> m_rgPusher;
+ CUtlVector<PhysicsPushedInfo_t> m_rgMoved;
+ int m_nBlocker;
+ bool m_bIsUnblockableByPlayer;
+ Vector m_rootPusherStartLocalOrigin;
+ QAngle m_rootPusherStartLocalAngles;
+ float m_rootPusherStartLocaltime;
+ float m_flMoveTime;
+
+ friend class CPushBlockerEnum;
+};
+
+class CTraceFilterPushMove : public CTraceFilterSimple
+{
+ DECLARE_CLASS( CTraceFilterPushMove, CTraceFilterSimple );
+
+public:
+ CTraceFilterPushMove( CBaseEntity *pEntity, int nCollisionGroup )
+ : CTraceFilterSimple( pEntity, nCollisionGroup )
+ {
+ m_pRootParent = pEntity->GetRootMoveParent();
+ }
+
+ bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
+ {
+ Assert( dynamic_cast<CBaseEntity*>(pHandleEntity) );
+ CBaseEntity *pTestEntity = static_cast<CBaseEntity*>(pHandleEntity);
+
+ if ( UTIL_EntityHasMatchingRootParent( m_pRootParent, pTestEntity ) )
+ return false;
+
+ if ( pTestEntity->GetMoveType() == MOVETYPE_VPHYSICS &&
+ pTestEntity->VPhysicsGetObject() && pTestEntity->VPhysicsGetObject()->IsMoveable() )
+ return false;
+
+ return BaseClass::ShouldHitEntity( pHandleEntity, contentsMask );
+ }
+
+private:
+
+ CBaseEntity *m_pRootParent;
+};
+
+extern CPhysicsPushedEntities *g_pPushedEntities;
+
+#endif // PUSHENTITY_H \ No newline at end of file