|
|
|
|
//========= Copyright <EFBFBD> 1996-2005, 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 CUtlVector< Vector > &vecOrigins, 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
|