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.
116 lines
4.1 KiB
116 lines
4.1 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#ifndef FUNC_AREAPORTALBASE_H |
|
#define FUNC_AREAPORTALBASE_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
|
|
#include "baseentity.h" |
|
#include "utllinkedlist.h" |
|
|
|
|
|
// Shared stuff between door portals and window portals. |
|
class CFuncAreaPortalBase : public CBaseEntity |
|
{ |
|
DECLARE_CLASS( CFuncAreaPortalBase, CBaseEntity ); |
|
public: |
|
DECLARE_DATADESC(); |
|
|
|
CFuncAreaPortalBase(); |
|
virtual ~CFuncAreaPortalBase(); |
|
|
|
// Areaportals must be placed in each map for preprocess, they can't use transitions |
|
virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } |
|
|
|
// This is called each frame for each client to all portals to close |
|
// when the viewer is far enough away, or on the backside. |
|
// |
|
// The default implementation closes the portal if the viewer (plus some padding) |
|
// is on the backside of the portal. Return false if you close the portal. |
|
// |
|
// Returns whether or not the (server part of) the engine was told to shut the |
|
// portal off for purposes of flowing through portals to determine which areas to |
|
// send to the client. |
|
// |
|
// |
|
// bIsOpenOnClient is usually the same as the return value but NOT always. Here's why (explained |
|
// here in depth because this case was discovered in a lengthy debugging session): |
|
// |
|
// - Each CFuncAreaPortalBase represents two dareaportal_t's (matched by CFuncAreaPortalBase::m_portalNumber |
|
// and dareaportal_t::m_PortalKey). Each dareaportal_t leads into one of the connected areas |
|
// and the dareaportal_t's have opposite-facing planes. |
|
// |
|
// - The engine's SetAreaPortalState function takes a portal key and closes BOTH dareaportal_t's associated with it. |
|
// |
|
// - UpdateVisibility may decide a portal leading out of the _area you're sitting in_ can be closed |
|
// for purposes of flowing through areas because you're on the backside of the dareaportal_t that |
|
// you would flow out of. |
|
// |
|
// - At the same time, you might be able to look through the other dareaportal_t attached to |
|
// that portal key (right back into the area you're standing in). |
|
// |
|
// - An illustration: |
|
// |
|
// -------------------- |
|
// | | |
|
// | |--------|aaaaaa| |
|
// | | |bbbbbb| <---- aaaa and bbbb area both for PortalKey1 |
|
// |**| | | |
|
// | | | area | |
|
// |**| | 2 | |
|
// | | |------| |
|
// | | | | |
|
// | ---------- area | |
|
// | 1 | |
|
// |------------------| |
|
// |
|
// "aaaa" and "bbbb" each represent a different dareaportal_t, (aaa leads into area 2 and |
|
// bbb leads into area 1). They both represent the same portal key though (call it PortalKey1). |
|
// |
|
// When standing in area 1 (where the "area 1" text is), the engine will check aaaa and it'll notice |
|
// that you're on the wrong side of aaaa to be looking through it, so it'll say that PortalKey1 is closed |
|
// for purposes of flowing through areas on the server (it turns out you can get to area 2 through |
|
// the portal right above the "area 1" text). |
|
// |
|
// If you told the client that PortalKey1 was closed, then you'd get a pop when moving from area 1 |
|
// to area 2 because the client would think you couldn't see through PortalKey1 into area 1 UNTIL |
|
// the server transmitted the new updated PortalKey bits, which can be lagged. |
|
// |
|
// That's why we have bIsOpenOnClient which doesn't include this backfacing test. |
|
// |
|
// .. and they all lived happily ever after. |
|
// The End |
|
// |
|
// |
|
// |
|
// Note: when you're standing in the space between the **'s, then the server would stop transmitting |
|
// the contents of area 2 because there would be no portal you were on the correct side of to |
|
// see into area 2. |
|
virtual bool UpdateVisibility( const Vector &vOrigin, float fovDistanceAdjustFactor, bool &bIsOpenOnClient ); |
|
|
|
|
|
public: |
|
|
|
// This matches two dareaportal_t::m_PortalKeys. |
|
int m_portalNumber; |
|
|
|
int m_iPortalVersion; |
|
|
|
private: |
|
|
|
unsigned short m_AreaPortalsElement; // link into g_AreaPortals. |
|
}; |
|
|
|
|
|
extern CUtlLinkedList<CFuncAreaPortalBase*, unsigned short> g_AreaPortals; |
|
|
|
|
|
|
|
#endif // FUNC_AREAPORTALBASE_H
|
|
|