source-engine/game/shared/obstacle_pushaway.h

188 lines
5.1 KiB
C
Raw Normal View History

2023-10-03 14:23:56 +00:00
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
2020-04-22 16:56:21 +00:00
//
// Purpose:
//
//=============================================================================//
#ifndef OBSTACLE_PUSHAWAY_H
#define OBSTACLE_PUSHAWAY_H
#ifdef _WIN32
#pragma once
#endif
#include "props_shared.h"
#ifndef CLIENT_DLL
#include "func_breakablesurf.h"
#include "BasePropDoor.h"
#include "doors.h"
#endif // CLIENT_DLL
//--------------------------------------------------------------------------------------------------------------
bool IsPushAwayEntity( CBaseEntity *pEnt );
bool IsPushableEntity( CBaseEntity *pEnt );
//--------------------------------------------------------------------------------------------------------------
#ifndef CLIENT_DLL
bool IsBreakableEntity( CBaseEntity *pEnt );
#endif // !CLIENT_DLL
//--------------------------------------------------------------------------------------------------------------
class CPushAwayEnumerator : public IPartitionEnumerator
{
public:
// Forced constructor
CPushAwayEnumerator(CBaseEntity **ents, int nMaxEnts)
{
m_nAlreadyHit = 0;
m_AlreadyHit = ents;
m_nMaxHits = nMaxEnts;
}
// Actual work code
virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity )
{
#ifdef CLIENT_DLL
CBaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( pHandleEntity->GetRefEHandle() );
#else
CBaseEntity *pEnt = gEntList.GetBaseEntity( pHandleEntity->GetRefEHandle() );
#endif // CLIENT_DLL
if ( IsPushAwayEntity( pEnt ) && m_nAlreadyHit < m_nMaxHits )
{
m_AlreadyHit[m_nAlreadyHit] = pEnt;
m_nAlreadyHit++;
}
return ITERATION_CONTINUE;
}
public:
CBaseEntity **m_AlreadyHit;
int m_nAlreadyHit;
int m_nMaxHits;
};
#ifndef CLIENT_DLL
//--------------------------------------------------------------------------------------------------------------
/**
* This class will collect breakable objects in a volume. Physics props that can be damaged, func_breakable*, etc
* are all collected by this class.
*/
class CBotBreakableEnumerator : public CPushAwayEnumerator
{
public:
CBotBreakableEnumerator(CBaseEntity **ents, int nMaxEnts) : CPushAwayEnumerator(ents, nMaxEnts)
{
}
virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity )
{
CBaseEntity *pEnt = gEntList.GetBaseEntity( pHandleEntity->GetRefEHandle() );
if ( !IsBreakableEntity( pEnt ) )
return ITERATION_CONTINUE;
// ignore breakables parented to doors
if ( pEnt->GetParent() &&
( FClassnameIs( pEnt->GetParent(), "func_door*" ) ||
FClassnameIs( pEnt, "prop_door*" ) ) )
return ITERATION_CONTINUE;
if ( m_nAlreadyHit < m_nMaxHits )
{
m_AlreadyHit[m_nAlreadyHit] = pEnt;
m_nAlreadyHit++;
}
return ITERATION_CONTINUE;
}
};
//--------------------------------------------------------------------------------------------------------------
/**
* This class will collect door objects in a volume.
*/
class CBotDoorEnumerator : public CPushAwayEnumerator
{
public:
CBotDoorEnumerator(CBaseEntity **ents, int nMaxEnts) : CPushAwayEnumerator(ents, nMaxEnts)
{
}
virtual IterationRetval_t EnumElement( IHandleEntity *pHandleEntity )
{
CBaseEntity *pEnt = gEntList.GetBaseEntity( pHandleEntity->GetRefEHandle() );
if ( pEnt == NULL )
return ITERATION_CONTINUE;
if ( ( pEnt->ObjectCaps() & FCAP_IMPULSE_USE ) == 0 )
{
return ITERATION_CONTINUE;
}
if ( FClassnameIs( pEnt, "func_door*" ) )
{
CBaseDoor *door = dynamic_cast<CBaseDoor *>(pEnt);
if ( !door )
{
return ITERATION_CONTINUE;
}
if ( door->m_toggle_state == TS_GOING_UP || door->m_toggle_state == TS_GOING_DOWN )
{
return ITERATION_CONTINUE;
}
}
else if ( FClassnameIs( pEnt, "prop_door*" ) )
{
CBasePropDoor *door = dynamic_cast<CBasePropDoor *>(pEnt);
if ( !door )
{
return ITERATION_CONTINUE;
}
if ( door->IsDoorOpening() || door->IsDoorClosing() )
{
return ITERATION_CONTINUE;
}
}
else
{
return ITERATION_CONTINUE;
}
if ( m_nAlreadyHit < m_nMaxHits )
{
m_AlreadyHit[m_nAlreadyHit] = pEnt;
m_nAlreadyHit++;
}
return ITERATION_CONTINUE;
}
};
//--------------------------------------------------------------------------------------------------------------
/**
* Returns an entity that matches the filter that is along the line segment
*/
CBaseEntity * CheckForEntitiesAlongSegment( const Vector &start, const Vector &end, const Vector &mins, const Vector &maxs, CPushAwayEnumerator *enumerator );
#endif // CLIENT_DLL
//--------------------------------------------------------------------------------------------------------------
// Retrieves physics objects near pPushingEntity
void AvoidPushawayProps( CBaseCombatCharacter *pPlayer, CUserCmd *pCmd );
int GetPushawayEnts( CBaseCombatCharacter *pPushingEntity, CBaseEntity **ents, int nMaxEnts, float flPlayerExpand, int PartitionMask, CPushAwayEnumerator *enumerator = NULL );
//--------------------------------------------------------------------------------------------------------------
// Pushes physics objects away from the entity
void PerformObstaclePushaway( CBaseCombatCharacter *pPushingEntity );
#endif // OBSTACLE_PUSHAWAY_H