diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/func_areaportalbase.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/server/func_areaportalbase.h')
| -rw-r--r-- | game/server/func_areaportalbase.h | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/game/server/func_areaportalbase.h b/game/server/func_areaportalbase.h new file mode 100644 index 0000000..ff6c167 --- /dev/null +++ b/game/server/func_areaportalbase.h @@ -0,0 +1,116 @@ +//========= 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 |