This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
nekohook/modules/source2013/sdk/game/server/func_areaportalbase.h
2020-08-04 13:13:01 -04:00

126 lines
4.5 KiB
C++

//========= 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