sqwarmed/sdk_src/game/server/pushentity.h

161 lines
5.4 KiB
C++

//====== Copyright © 1996-2008, 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, CBaseEntity *pRoot );
// Speculatively checks to see if all entities in this list can be pushed
virtual bool SpeculativelyCheckRotPush( const RotatingPushMove_t &rotPushMove, CBaseEntity *pRoot = NULL );
// 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