Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

231 lines
10 KiB

//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef PORTAL_BASE2D_H
#define PORTAL_BASE2D_H
#ifdef _WIN32
#pragma once
#endif
#include "baseanimating.h"
#include "PortalSimulation.h"
#include "pvs_extender.h"
#include "portal_base2d_shared.h"
// FIX ME
#include "portal_shareddefs.h"
class CPhysicsCloneArea;
class CPortal_Base2D : public CBaseAnimating, public CPortalSimulatorEventCallbacks, public CPVS_Extender, public CPortal_Base2D_Shared
{
public:
DECLARE_CLASS( CPortal_Base2D, CBaseAnimating );
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
CPortal_Base2D( void );
virtual ~CPortal_Base2D( void );
CNetworkHandle( CPortal_Base2D, m_hLinkedPortal ); //the portal this portal is linked to
VMatrix m_matrixThisToLinked; //the matrix that will transform a point relative to this portal, to a point relative to the linked portal
CNetworkVar( bool, m_bIsPortal2 ); //For teleportation, this doesn't matter, but for drawing and moving, it matters
Vector m_vPrevForward; //used for the indecisive push in find closest passable spaces when portal is moved
bool m_bSharedEnvironmentConfiguration; //this will be set by an instance of CPortal_Environment when two environments are in close proximity
EHANDLE m_hMicrophone; //the microphone for teleporting sound
EHANDLE m_hSpeaker; //the speaker for teleported sound
bool m_bMicAndSpeakersLinkedToRemote;
Vector m_vAudioOrigin;
Vector m_vDelayedPosition;
QAngle m_qDelayedAngles;
int m_iDelayedFailure;
Vector m_vOldPosition;
QAngle m_qOldAngles;
EHANDLE m_hPlacedBy;
int m_nPortalColor;
COutputEvent m_OnPlacedSuccessfully; // Output in hammer for when this portal was successfully placed (not attempted and fizzed).
COutputEvent m_OnEntityTeleportFromMe;
COutputEvent m_OnPlayerTeleportFromMe;
COutputEvent m_OnEntityTeleportToMe;
COutputEvent m_OnPlayerTeleportToMe;
CNetworkVector( m_ptOrigin );
Vector m_vForward, m_vUp, m_vRight;
CNetworkQAngle( m_qAbsAngle );
cplane_t m_plane_Origin; //a portal plane on the entity origin
CPhysicsCloneArea *m_pAttachedCloningArea;
bool IsPortal2() const;
void SetIsPortal2( bool bIsPortal2 );
const VMatrix& MatrixThisToLinked() const;
virtual int UpdateTransmitState( void ) // set transmit filter to transmit always
{
return SetTransmitState( FL_EDICT_ALWAYS );
}
virtual void Spawn( void );
virtual void Activate( void );
virtual void OnRestore( void );
virtual bool IsActive( void ) const { return m_bActivated; }
virtual bool GetOldActiveState( void ) const { return m_bOldActivatedState; }
virtual void SetActive( bool bActive );
virtual void UpdateOnRemove( void );
void TestRestingSurfaceThink( void );
static const char * s_szTestRestingSurfaceThinkContext;
void DeactivatePortalOnThink( void );
void DeactivatePortalNow( void );
static const char * s_szDeactivatePortalNowContext;
virtual void OnPortalDeactivated( void );
bool IsActivedAndLinked( void ) const;
bool IsFloorPortal( float fThreshold = 0.8f ) const;
bool IsCeilingPortal( float fThreshold = -0.8f ) const;
void WakeNearbyEntities( void ); //wakes all nearby entities in-case there's been a significant change in how they can rest near a portal
void ForceEntityToFitInPortalWall( CBaseEntity *pEntity ); //projects an object's center into the middle of the portal wall hall, and traces back to where it wants to be
virtual void NewLocation( const Vector &vOrigin, const QAngle &qAngles );
void PunchPenetratingPlayer( CBasePlayer *pPlayer ); // adds outward force to player intersecting the portal plane
void PunchAllPenetratingPlayers( void ); // adds outward force to player intersecting the portal plane
virtual void StartTouch( CBaseEntity *pOther );
virtual void Touch( CBaseEntity *pOther );
virtual void EndTouch( CBaseEntity *pOther );
bool ShouldTeleportTouchingEntity( CBaseEntity *pOther ); //assuming the entity is or was just touching the portal, check for teleportation conditions
void TeleportTouchingEntity( CBaseEntity *pOther );
virtual void PreTeleportTouchingEntity( CBaseEntity *pOther ) {};
virtual void PostTeleportTouchingEntity( CBaseEntity *pOther ) {};
virtual void PhysicsSimulate( void );
virtual void UpdatePortalLinkage( void );
void UpdatePortalTeleportMatrix( void ); //computes the transformation from this portal to the linked portal, and will update the remote matrix as well
//void SendInteractionMessage( CBaseEntity *pEntity, bool bEntering ); //informs clients that the entity is interacting with a portal (mostly used for clip planes)
bool SharedEnvironmentCheck( CBaseEntity *pEntity ); //does all testing to verify that the object is better handled with this portal instead of the other
// The four corners of the portal in worldspace, updated on placement. The four points will be coplanar on the portal plane.
Vector m_vPortalCorners[4];
CNetworkVarEmbedded( CPortalSimulator, m_PortalSimulator );
//virtual bool CreateVPhysics( void );
//virtual void VPhysicsDestroyObject( void );
virtual bool TestCollision( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );
virtual void PortalSimulator_TookOwnershipOfEntity( CBaseEntity *pEntity );
virtual void PortalSimulator_ReleasedOwnershipOfEntity( CBaseEntity *pEntity );
virtual void CreateMicAndSpeaker( void );
// Add or remove listeners
void AddPortalEventListener( EHANDLE hListener );
void RemovePortalEventListener( EHANDLE hListener );
void OnEntityTeleportedToPortal( CBaseEntity *pEntity );
void OnEntityTeleportedFromPortal( CBaseEntity *pEntity );
protected:
CNetworkVar( bool, m_bActivated ); //a portal can exist and not be active
CNetworkVar( bool, m_bOldActivatedState ); //the old state
void BroadcastPortalEvent( PortalEvent_t nEventType );
CUtlVector<EHANDLE> m_PortalEventListeners; // Collection of entities (by handle) who wish to receive notification of portal events (fizzle, moved, etc)
void RemovePortalMicAndSpeaker(); // Cleans up the portal's internal audio members
void UpdateCorners( void ); // Updates the four corners of this portal on spawn and placement
void UpdateClientCheckPVS( void ); // Tells clients to update the cached PVS in g_ClientCheck
void UpdateCollisionShape( void );
CNetworkVar( float, m_fNetworkHalfWidth );
CNetworkVar( float, m_fNetworkHalfHeight );
CNetworkVar( bool, m_bIsMobile ); //is this portal currently making small movements along with whatever brush it's attached to? Portal physics are disabled while nudging and resume when stabilized
CPhysCollide *m_pCollisionShape;
public:
CPortal_Base2D *GetLinkedPortal( void ) { return m_hLinkedPortal; }
inline float GetHalfWidth( void ) const { return m_fNetworkHalfWidth; }
inline float GetHalfHeight( void ) const { return m_fNetworkHalfHeight; }
inline Vector GetLocalMins( void ) const { return Vector( 0.0f, -m_fNetworkHalfWidth, -m_fNetworkHalfHeight ); }
inline Vector GetLocalMaxs( void ) const { return Vector( 64.0f, m_fNetworkHalfWidth, m_fNetworkHalfHeight ); }
//inline void SetHalfSizes( float fHalfWidth, float fHalfHeight ) { m_fHalfWidth = fHalfWidth; m_fHalfHeight = fHalfHeight; }
inline bool IsMobile( void ) const { return m_bIsMobile; }
void SetMobileState( bool bSet );
void Resize( float fHalfWidth, float fHalfHeight );
virtual CServerNetworkProperty *GetExtenderNetworkProp( void );
virtual const edict_t *GetExtenderEdict( void ) const;
virtual Vector GetExtensionPVSOrigin( void );
virtual bool IsExtenderValid( void );
//to whittle down views through recursive portals, we clip the portal's planar polygon by a frustum, then fit a new (smaller) frustum to that polygon. These two let you specify the polygon we clip and fit to
virtual int GetPolyVertCount( void );
virtual int ComputeFrustumThroughPolygon( const Vector &vVisOrigin, const VPlane *pInputFrustum, int iInputFrustumPlanes, VPlane *pOutputFrustum, int iOutputFrustumMaxPlanes );
//This portal is decidedly visible, recursively extend the visibility problem
virtual void ComputeSubVisibility( CPVS_Extender **pExtenders, int iExtenderCount, unsigned char *outputPVS, int pvssize, const Vector &vVisOrigin, const VPlane *pVisFrustum, int iVisFrustumPlanes, VisExtensionChain_t *pVisChain, int iAreasNetworked[MAX_MAP_AREAS], int iMaxRecursionsLeft );
//it shouldn't matter, but the convention should be that we query the exit portal for these values
virtual float GetMinimumExitSpeed( bool bPlayer, bool bEntranceOnFloor, bool bExitOnFloor, const Vector &vEntityCenterAtExit, CBaseEntity *pEntity ); //return -FLT_MAX for no minimum
virtual float GetMaximumExitSpeed( bool bPlayer, bool bEntranceOnFloor, bool bExitOnFloor, const Vector &vEntityCenterAtExit, CBaseEntity *pEntity ); //return FLT_MAX for no maximum
//does all the gruntwork of figuring out flooriness and calling the two above
static void GetExitSpeedRange( CPortal_Base2D *pEntrancePortal, bool bPlayer, float &fExitMinimum, float &fExitMaximum, const Vector &vEntityCenterAtExit, CBaseEntity *pEntity );
private:
Vector m_vPortalSpawnLocation; // use this position to check against portal->AbsOrigin of the portal to see if it's moving too far (moving portal is very bad)
};
//-----------------------------------------------------------------------------
// inline state querying methods
//-----------------------------------------------------------------------------
inline bool CPortal_Base2D::IsPortal2() const
{
return m_bIsPortal2;
}
inline void CPortal_Base2D::SetIsPortal2( bool bIsPortal2 )
{
m_bIsPortal2 = bIsPortal2;
}
inline const VMatrix& CPortal_Base2D::MatrixThisToLinked() const
{
return m_matrixThisToLinked;
}
void AddPortalVisibilityToPVS( CPortal_Base2D* pPortal, int outputpvslength, unsigned char *outputpvs );
void EntityPortalled( CPortal_Base2D *pPortal, CBaseEntity *pOther, const Vector &vNewOrigin, const QAngle &qNewAngles, bool bForcedDuck );
extern ConVar sv_allow_mobile_portals;
#endif //#ifndef PORTAL_BASE2D_H