Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef FUNC_AREAPORTALBASE_H
  8. #define FUNC_AREAPORTALBASE_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "baseentity.h"
  13. #include "utllinkedlist.h"
  14. // Shared stuff between door portals and window portals.
  15. class CFuncAreaPortalBase : public CBaseEntity
  16. {
  17. DECLARE_CLASS( CFuncAreaPortalBase, CBaseEntity );
  18. public:
  19. DECLARE_DATADESC();
  20. CFuncAreaPortalBase();
  21. virtual ~CFuncAreaPortalBase();
  22. // Areaportals must be placed in each map for preprocess, they can't use transitions
  23. virtual int ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
  24. // This is called each frame for each client to all portals to close
  25. // when the viewer is far enough away, or on the backside.
  26. //
  27. // The default implementation closes the portal if the viewer (plus some padding)
  28. // is on the backside of the portal. Return false if you close the portal.
  29. //
  30. // Returns whether or not the (server part of) the engine was told to shut the
  31. // portal off for purposes of flowing through portals to determine which areas to
  32. // send to the client.
  33. //
  34. //
  35. // bIsOpenOnClient is usually the same as the return value but NOT always. Here's why (explained
  36. // here in depth because this case was discovered in a lengthy debugging session):
  37. //
  38. // - Each CFuncAreaPortalBase represents two dareaportal_t's (matched by CFuncAreaPortalBase::m_portalNumber
  39. // and dareaportal_t::m_PortalKey). Each dareaportal_t leads into one of the connected areas
  40. // and the dareaportal_t's have opposite-facing planes.
  41. //
  42. // - The engine's SetAreaPortalState function takes a portal key and closes BOTH dareaportal_t's associated with it.
  43. //
  44. // - UpdateVisibility may decide a portal leading out of the _area you're sitting in_ can be closed
  45. // for purposes of flowing through areas because you're on the backside of the dareaportal_t that
  46. // you would flow out of.
  47. //
  48. // - At the same time, you might be able to look through the other dareaportal_t attached to
  49. // that portal key (right back into the area you're standing in).
  50. //
  51. // - An illustration:
  52. //
  53. // --------------------
  54. // | |
  55. // | |--------|aaaaaa|
  56. // | | |bbbbbb| <---- aaaa and bbbb area both for PortalKey1
  57. // |**| | |
  58. // | | | area |
  59. // |**| | 2 |
  60. // | | |------|
  61. // | | | |
  62. // | ---------- area |
  63. // | 1 |
  64. // |------------------|
  65. //
  66. // "aaaa" and "bbbb" each represent a different dareaportal_t, (aaa leads into area 2 and
  67. // bbb leads into area 1). They both represent the same portal key though (call it PortalKey1).
  68. //
  69. // When standing in area 1 (where the "area 1" text is), the engine will check aaaa and it'll notice
  70. // that you're on the wrong side of aaaa to be looking through it, so it'll say that PortalKey1 is closed
  71. // for purposes of flowing through areas on the server (it turns out you can get to area 2 through
  72. // the portal right above the "area 1" text).
  73. //
  74. // If you told the client that PortalKey1 was closed, then you'd get a pop when moving from area 1
  75. // to area 2 because the client would think you couldn't see through PortalKey1 into area 1 UNTIL
  76. // the server transmitted the new updated PortalKey bits, which can be lagged.
  77. //
  78. // That's why we have bIsOpenOnClient which doesn't include this backfacing test.
  79. //
  80. // .. and they all lived happily ever after.
  81. // The End
  82. //
  83. //
  84. //
  85. // Note: when you're standing in the space between the **'s, then the server would stop transmitting
  86. // the contents of area 2 because there would be no portal you were on the correct side of to
  87. // see into area 2.
  88. virtual bool UpdateVisibility( const Vector &vOrigin, float fovDistanceAdjustFactor, bool &bIsOpenOnClient );
  89. public:
  90. // This matches two dareaportal_t::m_PortalKeys.
  91. int m_portalNumber;
  92. int m_iPortalVersion;
  93. private:
  94. unsigned short m_AreaPortalsElement; // link into g_AreaPortals.
  95. };
  96. extern CUtlLinkedList<CFuncAreaPortalBase*, unsigned short> g_AreaPortals;
  97. #endif // FUNC_AREAPORTALBASE_H