Counter Strike : Global Offensive Source Code
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.

540 lines
18 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Defines a common class for all objects in the world object tree.
  4. //
  5. // Pointers to other objects in the object tree may be stored, but
  6. // they should be set via UpdateDependency rather than directly. This
  7. // insures proper linkage to the other object so that if it moves, is
  8. // removed from the world, or changes in any other way, the dependent
  9. // object is properly notified.
  10. //
  11. //=============================================================================//
  12. #ifndef MAPCLASS_H
  13. #define MAPCLASS_H
  14. #ifdef _WIN32
  15. #pragma once
  16. #endif
  17. #include "tier0/basetypes.h"
  18. #pragma warning(push, 1)
  19. #pragma warning(disable:4701 4702 4530)
  20. #include <fstream>
  21. #pragma warning(pop)
  22. #include "BoundBox.h"
  23. #include "MapPoint.h"
  24. #include "UtlVector.h"
  25. #include "visgroup.h"
  26. #include "fgdlib/wckeyvalues.h"
  27. #include "tier1/smartptr.h"
  28. #include "tier1/utlobjectreference.h"
  29. class Box3D;
  30. class CBaseTool;
  31. class CChunkFile;
  32. class GDclass;
  33. class CMapClass;
  34. class CMapEntity;
  35. class CMapSolid;
  36. class CMapView2D;
  37. class CMapViewLogical;
  38. class CMapWorld;
  39. class CPoint;
  40. class CRender3D;
  41. class CSaveInfo;
  42. class CSSolid;
  43. class CVisGroupList;
  44. class CMapFaceList;
  45. struct MapError;
  46. enum ChunkFileResult_t;
  47. struct MapObjectPair_t
  48. {
  49. CMapClass *pObject1;
  50. CMapClass *pObject2;
  51. };
  52. //-----------------------------------------------------------------------------
  53. // Structure used for returning hits when calling ObjectsAt.
  54. //-----------------------------------------------------------------------------
  55. typedef struct HitInfo_s
  56. {
  57. CMapClass *pObject; // Pointer to the CMapAtom that was clicked on.
  58. unsigned int uData; // Additional data provided by the CMapAtom object.
  59. unsigned int nDepth; // Depth value of the object that was clicked on.
  60. VMatrix m_LocalMatrix;
  61. } HitInfo_t;
  62. //
  63. // Passed into PrepareSelection to control what gets selected.
  64. //
  65. enum SelectMode_t
  66. {
  67. selectGroups = 0, // select groups, ungrouped entities, and ungrouped solids
  68. selectObjects, // select entities and solids not in entities
  69. selectSolids, // select point entities, solids in entities, solids
  70. };
  71. enum VisGroupSelection
  72. {
  73. AUTO = 0,
  74. USER
  75. };
  76. // helper macro for linked lists as pointers
  77. #define FOR_EACH_OBJ( listName, iteratorName ) \
  78. for( int iteratorName=0; iteratorName<(listName).Count(); iteratorName++)
  79. typedef const char * MAPCLASSTYPE;
  80. typedef BOOL (*ENUMMAPCHILDRENPROC)(CMapClass *, unsigned int dwParam);
  81. typedef CUtlReferenceVector< CMapClass > CMapObjectList;
  82. typedef CUtlReferenceVector< CMapClass > CMapObjectRefList;
  83. #define MAX_ENUM_CHILD_DEPTH 16
  84. struct EnumChildrenStackEntry_t
  85. {
  86. CMapClass *pParent;
  87. int pos;
  88. };
  89. struct EnumChildrenPos_t
  90. {
  91. EnumChildrenStackEntry_t Stack[MAX_ENUM_CHILD_DEPTH];
  92. int nDepth;
  93. };
  94. typedef struct
  95. {
  96. MAPCLASSTYPE Type;
  97. CMapClass * (*pfnNew)();
  98. } MCMSTRUCT;
  99. class CMapClass : public CMapPoint
  100. {
  101. DECLARE_REFERENCED_CLASS( CMapClass );
  102. public:
  103. //
  104. // Construction/destruction:
  105. //
  106. CMapClass(void);
  107. virtual ~CMapClass(void);
  108. inline int GetID(void) const;
  109. inline int GetHammerID(void) const { return GetID(); }
  110. inline void SetID(int nID);
  111. inline int GetLoadID() const; // PORTAL2 SHIP: keep track of load order to preserve it on save so that maps can be diffed.
  112. virtual size_t GetSize(void);
  113. //
  114. // Can belong to one or more visgroups:
  115. //
  116. virtual void AddVisGroup(CVisGroup *pVisGroup);
  117. int GetVisGroupCount(void);
  118. CVisGroup *GetVisGroup(int nIndex);
  119. void RemoveAllVisGroups(void);
  120. void RemoveVisGroup(CVisGroup *pVisGroup);
  121. int IsInVisGroup(CVisGroup *pVisGroup);
  122. void SetColorVisGroup(CVisGroup *pVisGroup);
  123. virtual bool UpdateObjectColor();
  124. //
  125. // Can be tracked in the Undo/Redo system:
  126. //
  127. inline void SetTemporary(bool bTemporary) { m_bTemporary = bTemporary; }
  128. inline bool IsTemporary(void) const { return m_bTemporary; }
  129. union
  130. {
  131. struct
  132. {
  133. unsigned ID : 28;
  134. unsigned Types : 4; // 0 - copy, 1 - relationship, 2 - delete
  135. } Kept;
  136. unsigned int dwKept;
  137. };
  138. //
  139. // Has children:
  140. //
  141. virtual void AddChild(CMapClass *pChild);
  142. virtual void CopyChildrenFrom(CMapClass *pobj, bool bUpdateDependencies);
  143. virtual void RemoveAllChildren(void);
  144. virtual void RemoveChild(CMapClass *pChild, bool bUpdateBounds = true);
  145. virtual void UpdateChild(CMapClass *pChild);
  146. inline int GetChildCount(void) { return( m_Children.Count()); }
  147. inline const CMapObjectList *GetChildren() { return &m_Children; }
  148. CMapClass *GetFirstDescendent(EnumChildrenPos_t &pos);
  149. CMapClass *GetNextDescendent(EnumChildrenPos_t &pos);
  150. virtual CMapClass *GetParent(void)
  151. {
  152. Assert( (m_pParent == NULL) || (dynamic_cast<CMapClass*>(m_pParent) != NULL) );
  153. return( (CMapClass*)m_pParent);
  154. }
  155. virtual void SetParent(CMapAtom *pParent)
  156. {
  157. Assert( (pParent == NULL) || (dynamic_cast<CMapClass*>(pParent) != NULL) );
  158. UpdateParent((CMapClass*)pParent);
  159. }
  160. const CMapObjectRefList *GetDependents() { return &m_Dependents; }
  161. virtual void FindTargetNames( CUtlVector< const char * > &Names ) { }
  162. virtual void ReplaceTargetname(const char *szOldName, const char *szNewName);
  163. //
  164. // Notifications.
  165. //
  166. virtual void OnAddToWorld(CMapWorld *pWorld);
  167. virtual void OnClone(CMapClass *pClone, CMapWorld *pWorld, const CMapObjectList &OriginalList, CMapObjectList &NewList);
  168. virtual void OnPreClone(CMapClass *pClone, CMapWorld *pWorld, const CMapObjectList &OriginalList, CMapObjectList &NewList);
  169. virtual void OnPrePaste(CMapClass *pCopy, CMapWorld *pSourceWorld, CMapWorld *pDestWorld, const CMapObjectList &OriginalList, CMapObjectList &NewList);
  170. virtual void OnPaste(CMapClass *pCopy, CMapWorld *pSourceWorld, CMapWorld *pDestWorld, const CMapObjectList &OriginalList, CMapObjectList &NewList);
  171. virtual void OnNotifyDependent(CMapClass *pObject, Notify_Dependent_t eNotifyType);
  172. virtual void OnParentKeyChanged(const char* key, const char* value) {}
  173. virtual void OnRemoveFromWorld(CMapWorld *pWorld, bool bNotifyChildren);
  174. virtual void OnUndoRedo(void) {}
  175. virtual bool OnApply( void ) { return true; }
  176. //
  177. // Bounds calculation and intersection functions.
  178. //
  179. virtual void CalcBounds(BOOL bFullUpdate = FALSE);
  180. void GetCullBox(Vector &mins, Vector &maxs) const;
  181. inline const Vector &GetCullBoxMins() const;
  182. inline const Vector &GetCullBoxMaxs() const;
  183. void SetCullBoxFromFaceList( CMapFaceList *pFaces );
  184. void GetBoundingBox( Vector &mins, Vector &maxs );
  185. void SetBoundingBoxFromFaceList( CMapFaceList *pFaces );
  186. void GetRender2DBox(Vector &mins, Vector &maxs);
  187. // NOTE: Logical position is in global space
  188. virtual void SetLogicalPosition( const Vector2D &vecPosition ) {}
  189. virtual const Vector2D& GetLogicalPosition( );
  190. // NOTE: Logical bounds is in global space
  191. virtual void GetRenderLogicalBox( Vector2D &mins, Vector2D &maxs );
  192. // HACK: temp stuff to ease the transition to not inheriting from BoundBox
  193. void GetBoundsCenter(Vector &vecCenter) { m_Render2DBox.GetBoundsCenter(vecCenter); }
  194. void GetBoundsSize(Vector &vecSize) { m_Render2DBox.GetBoundsSize(vecSize); }
  195. inline bool IsInsideBox(Vector const &Mins, Vector const &Maxs) const { return(m_Render2DBox.IsInsideBox(Mins, Maxs)); }
  196. inline bool IsIntersectingBox(const Vector &vecMins, const Vector& vecMaxs) const { return(m_Render2DBox.IsIntersectingBox(vecMins, vecMaxs)); }
  197. inline bool ContainsPoint(const Vector &vecPoint) const { return(m_Render2DBox.ContainsPoint(vecPoint)); }
  198. virtual CMapClass *PrepareSelection(SelectMode_t eSelectMode);
  199. void PostUpdate(Notify_Dependent_t eNotifyType);
  200. static void UpdateAllDependencies(CMapClass *pObject);
  201. void SetOrigin(Vector& origin);
  202. // hierarchy
  203. virtual void UpdateAnimation( float animTime ) {}
  204. virtual bool GetTransformMatrix( VMatrix& matrix );
  205. virtual MAPCLASSTYPE GetType(void) const = 0;
  206. virtual BOOL IsMapClass(MAPCLASSTYPE Type) const = 0;
  207. virtual bool IsWorld() { return false; }
  208. virtual CMapClass *Copy(bool bUpdateDependencies);
  209. virtual CMapClass *CopyFrom(CMapClass *pFrom, bool bUpdateDependencies);
  210. virtual bool HitTest2D(CMapView2D *pView, const Vector2D &point, HitInfo_t &HitData);
  211. virtual bool HitTestLogical(CMapViewLogical *pView, const Vector2D &point, HitInfo_t &HitData);
  212. // Objects that can be clicked on and activated as tools implement this and return a CBaseTool-derived object.
  213. virtual CBaseTool *GetToolObject(int nHitData, bool bAttachObject) { return NULL; }
  214. //
  215. // Can be serialized:
  216. //
  217. virtual ChunkFileResult_t SaveVMF(CChunkFile *pFile, CSaveInfo *pSaveInfo);
  218. virtual ChunkFileResult_t SaveEditorData(CChunkFile *pFile);
  219. virtual bool ShouldSerialize(void) { return true; }
  220. virtual int SerializeRMF(std::fstream &File, BOOL bRMF);
  221. virtual int SerializeMAP(std::fstream &File, BOOL bRMF);
  222. virtual void PostloadWorld(CMapWorld *pWorld);
  223. virtual void PresaveWorld(void) {}
  224. bool PostloadVisGroups( bool bIsLoading );
  225. virtual bool IsGroup(void) const { return false; }
  226. virtual bool IsScaleable(void) const { return false; }
  227. virtual bool IsClutter(void) const { return false; } // Whether this object should be hidden when the user hides helpers.
  228. virtual bool CanBeCulledByCordon() const { return true; } // Whether this object cares about cordons at all
  229. virtual bool IsIntersectingCordon(const Vector &vecMins, const Vector &vecMaxs); // Whether this object is visible based on its intersection with the given cordon bounds
  230. virtual bool IsEditable( void );
  231. virtual bool ShouldSnapToHalfGrid() { return false; }
  232. virtual bool IsSolid( ) { return false; }
  233. // searching
  234. virtual CMapEntity *FindChildByKeyValue( const char* key, const char* value, bool *bIsInInstance = NULL, VMatrix *InstanceMatrix = NULL );
  235. // HACK: get the world that this object is contained within.
  236. static CMapWorld *GetWorldObject(CMapAtom *pStart);
  237. virtual const char* GetDescription() { return ""; }
  238. BOOL EnumChildren(ENUMMAPCHILDRENPROC pfn, unsigned int dwParam = 0, MAPCLASSTYPE Type = NULL);
  239. BOOL EnumChildrenRecurseGroupsOnly(ENUMMAPCHILDRENPROC pfn, unsigned int dwParam, MAPCLASSTYPE Type = NULL);
  240. BOOL EnumChildrenAndInstances( ENUMMAPCHILDRENPROC pfn, unsigned int dwParam, MAPCLASSTYPE Type = NULL );
  241. BOOL IsChildOf(CMapAtom *pObject);
  242. virtual bool ShouldAppearInLightingPreview(void)
  243. {
  244. return true; //false;
  245. }
  246. virtual bool ShouldAppearInRaytracedLightingPreview(void)
  247. {
  248. return false;
  249. }
  250. // When rendering the 3D view on top of the engine's 3D view, should this thing be rendered? (Brushes don't render).
  251. virtual bool ShouldAppearOverEngine(void)
  252. {
  253. return true;
  254. }
  255. inline bool IsVisible(void) const { return(m_bVisible); }
  256. void SetVisible(bool bVisible);
  257. inline bool IsVisGroupShown(void) const { return m_bVisGroupShown && m_bVisGroupAutoShown; }
  258. void VisGroupShow(bool bShow, VisGroupSelection eVisGroup = USER);
  259. bool CheckVisibility(bool bIsLoading = false);
  260. //
  261. // Visible2D functions are used only for hiding solids being morphed. Remove?
  262. //
  263. bool IsVisible2D(void) { return m_bVisible2D; }
  264. void SetVisible2D(bool bVisible2D) { m_bVisible2D = bVisible2D; }
  265. // Is this class potentially visible in 2D visio view?
  266. virtual bool IsLogical(void) { return false; }
  267. // Is this class actually visible in 2D visio view?
  268. virtual bool IsVisibleLogical(void) { return false; }
  269. //
  270. // Overridden to set the render color of each of our children.
  271. //
  272. virtual void SetRenderColor(unsigned char red, unsigned char green, unsigned char blue);
  273. virtual void SetRenderColor(color32 rgbColor);
  274. //
  275. // Can be rendered:
  276. //
  277. virtual void Render2D(CRender2D *pRender);
  278. virtual void Render3D(CRender3D *pRender);
  279. virtual void RenderLogical( CRender2D *pRender ) {}
  280. virtual bool RenderPreload(CRender3D *pRender, bool bNewContext);
  281. inline int GetRenderFrame(void) { return(m_nRenderFrame); }
  282. inline void SetRenderFrame(int nRenderFrame) { m_nRenderFrame = nRenderFrame; }
  283. SelectionState_t SetSelectionState(SelectionState_t eSelectionState);
  284. //
  285. // Has a set of editor-specific properties that are loaded from the VMF file.
  286. // The keys are freed after being handled by the map post-load code.
  287. //
  288. int GetEditorKeyCount(void);
  289. const char *GetEditorKey(int nIndex);
  290. const char *GetEditorKeyValue(int nIndex);
  291. const char *GetEditorKeyValue(const char *szKey);
  292. void RemoveEditorKeys(void);
  293. void SetEditorKeyValue(const char *szKey, const char *szValue);
  294. virtual void InstanceMoved( void );
  295. // Methods for working with temporary markers to track objects already processed by the current drop trace
  296. inline void DropTraceMark();
  297. inline bool IsDropTraceMarkerCurrent();
  298. inline static void MakeNewDropTraceMarker();
  299. public:
  300. // Set to true while loading a VMF file so it can delay certain calls like UpdateBounds.
  301. // Drastically speeds up load times.
  302. static bool s_bLoadingVMF;
  303. protected:
  304. //
  305. // Implements CMapAtom transformation interface:
  306. //
  307. virtual void DoTransform(const VMatrix &matrix);
  308. //
  309. // Serialization callbacks.
  310. //
  311. static ChunkFileResult_t LoadEditorCallback(CChunkFile *pFile, CMapClass *pObject);
  312. static ChunkFileResult_t LoadEditorKeyCallback(const char *szKey, const char *szValue, CMapClass *pObject);
  313. //
  314. // Has a list of objects that must be notified if it changes size or position.
  315. //
  316. void AddDependent(CMapClass *pDependent);
  317. void NotifyDependents(Notify_Dependent_t eNotifyType);
  318. void RemoveDependent(CMapClass *pDependent);
  319. virtual void UpdateDependencies(CMapWorld *pWorld, CMapClass *pObject) {};
  320. CMapClass *UpdateDependency(CMapClass *pOldAttached, CMapClass *pNewAttached);
  321. void UpdateParent(CMapClass *pNewParent);
  322. void SetBoxFromFaceList( CMapFaceList *pFaces, BoundBox &Box );
  323. BoundBox m_CullBox; // Our bounds for culling in the 3D views and intersecting with the cordon.
  324. BoundBox m_BoundingBox; // Our bounds for brushes / entities themselves. This size may be smaller than m_CullBox ( i.e. spheres are not included )
  325. BoundBox m_Render2DBox; // Our bounds for rendering in the 2D views.
  326. CMapObjectList m_Children; // Each object can have many children. Children usually transform with their parents, etc.
  327. CMapObjectRefList m_Dependents; // Objects that this object should notify if it changes.
  328. int m_nID; // This object's unique ID.
  329. int m_nLoadID; // PORTAL2 SHIP: keep track of load order to preserve it on save so that maps can be diffed.
  330. bool m_bTemporary; // Whether to track this object for Undo/Redo.
  331. int m_nRenderFrame; // Frame counter used to avoid rendering the same object twice in a 3D frame.
  332. bool m_bVisible2D : 1; // Whether this object is visible in the 2D view. Currently only used for morphing.
  333. bool m_bVisible : 1; // Whether this object is currently visible in the 2D and 3D views based on ALL factors: visgroups, cordon, etc.
  334. bool m_bVisGroupShown; // Whether this object is shown or hidden by user visgroups. Kept separate from m_bVisible so we can
  335. // reflect this state in the visgroups list independent of the cordon, hide entities state, etc.
  336. bool m_bVisGroupAutoShown; // Whether this object is shown or hidden by auto visgroups.
  337. CVisGroupList m_VisGroups; // Visgroups to which this object belongs, EMPTY if none.
  338. CVisGroup *m_pColorVisGroup; // The visgroup from which we get our color, NULL if none.
  339. WCKeyValuesT<WCKVBase_Vector> *m_pEditorKeys; // Temporary storage for keys loaded from the "editor" chunk of the VMF file, freed after loading.
  340. friend class CTrackEntry; // Friends with Undo/Redo system so that parentage can be changed.
  341. friend void FixHiddenObject(MapError *pError); // So that the Check for Problems dialog can fix visgroups problems.
  342. int m_nDropTraceMarker; // A temporary working value that tracks whether this object has been touched by the drop trace
  343. static int sm_nDropTraceMarker; // Current global grid nav marker value
  344. };
  345. //-----------------------------------------------------------------------------
  346. // Returns this object's unique ID.
  347. //-----------------------------------------------------------------------------
  348. int CMapClass::GetID() const
  349. {
  350. return(m_nID);
  351. }
  352. //-----------------------------------------------------------------------------
  353. // Sets this object's unique ID.
  354. //-----------------------------------------------------------------------------
  355. void CMapClass::SetID(int nID)
  356. {
  357. m_nID = nID;
  358. }
  359. //-----------------------------------------------------------------------------
  360. // PORTAL2 SHIP: keep track of load order to preserve it on save so that maps can be diffed.
  361. //-----------------------------------------------------------------------------
  362. int CMapClass::GetLoadID() const
  363. {
  364. return m_nLoadID;
  365. }
  366. void CMapClass::DropTraceMark()
  367. {
  368. m_nDropTraceMarker = sm_nDropTraceMarker;
  369. }
  370. bool CMapClass::IsDropTraceMarkerCurrent()
  371. {
  372. return m_nDropTraceMarker == sm_nDropTraceMarker;
  373. }
  374. void CMapClass::MakeNewDropTraceMarker()
  375. {
  376. ++sm_nDropTraceMarker; // Note: Overflow is currently possible, which could lead to undefined behavior after >4 billion calls. Seems unlikely to happen in practice.
  377. }
  378. const Vector &CMapClass::GetCullBoxMins() const
  379. {
  380. return m_CullBox.bmins;
  381. }
  382. const Vector &CMapClass::GetCullBoxMaxs() const
  383. {
  384. return m_CullBox.bmaxs;
  385. }
  386. class CMapClassManager
  387. {
  388. public:
  389. virtual ~CMapClassManager();
  390. CMapClassManager(MAPCLASSTYPE Type, CMapClass * (*pfnNew)());
  391. static CMapClass * CreateObject(MAPCLASSTYPE Type);
  392. };
  393. #define MAPCLASS_TYPE(class_name) \
  394. (class_name::__Type)
  395. #define IMPLEMENT_MAPCLASS(class_name) \
  396. char * class_name::__Type = #class_name; \
  397. MAPCLASSTYPE class_name::GetType() const { return __Type; } \
  398. BOOL class_name::IsMapClass(MAPCLASSTYPE Type) const \
  399. { return (Type == __Type) ? TRUE : FALSE; } \
  400. CMapClass * class_name##_CreateObject() \
  401. { return new class_name; } \
  402. CMapClassManager mcm_##class_name(class_name::__Type, \
  403. class_name##_CreateObject);
  404. #define DECLARE_MAPCLASS(class_name,class_base) \
  405. typedef class_base BaseClass; \
  406. static char * __Type; \
  407. virtual MAPCLASSTYPE GetType() const; \
  408. virtual BOOL IsMapClass(MAPCLASSTYPE Type) const;
  409. class CCheckFaceInfo
  410. {
  411. public:
  412. CCheckFaceInfo() { iPoint = -1; }
  413. char szDescription[128];
  414. int iPoint;
  415. };
  416. #endif // MAPCLASS_H