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.

660 lines
22 KiB

  1. //========= Copyright � 1996-2009, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Declares the base class for all paint power users.
  4. //
  5. //=============================================================================//
  6. #ifndef PAINT_POWER_USER_H
  7. #define PAINT_POWER_USER_H
  8. #include <utility>
  9. #include <algorithm>
  10. #include "gamestringpool.h"
  11. #include "paint_power_user_interface.h"
  12. #include "portal_player_shared.h"
  13. #include "paint_power_info.h"
  14. extern ConVar sv_enable_paint_power_user_debug;
  15. //#define PAINT_POWER_USER_DEBUG
  16. char const* const PAINT_POWER_USER_DATA_CLASS_NAME = "PaintPowerUser";
  17. const int MAX_PAINT_SURFACE_CONTEXT_LENGTH = 32;
  18. template< typename T >
  19. inline T* GetBegin( CUtlVector<T>& v )
  20. {
  21. return v.Base();
  22. }
  23. template< typename T >
  24. inline T* GetEnd( CUtlVector<T>& v )
  25. {
  26. return v.Base() + v.Count();
  27. }
  28. template< typename T >
  29. inline const T* GetConstBegin( const CUtlVector<T>& v )
  30. {
  31. return v.Base();
  32. }
  33. template< typename T >
  34. inline const T* GetConstEnd( const CUtlVector<T>& v )
  35. {
  36. return v.Base() + v.Count();
  37. }
  38. template< typename T >
  39. inline const std::pair< T*, T* > GetRange( CUtlVector< T >& v )
  40. {
  41. return std::pair< T*, T* >( v.Base(), v.Base() + v.Count() );
  42. }
  43. template< typename T >
  44. inline const std::pair< const T*, const T* > GetConstRange( const CUtlVector< T >& v )
  45. {
  46. return std::pair< const T*, const T* >( v.Base(), v.Base() + v.Count() );
  47. }
  48. template< typename IteratorType >
  49. inline int GetCountFromRange( const std::pair< IteratorType, IteratorType >& range )
  50. {
  51. return range.second - range.first;
  52. }
  53. template< typename IteratorType >
  54. inline bool IsEmptyRange( const std::pair< IteratorType, IteratorType >& range )
  55. {
  56. return range.first == range.second;
  57. }
  58. //=============================================================================
  59. // class PaintPowerUser
  60. // Purpose: Base class for entities which use paint powers.
  61. //=============================================================================
  62. template< typename BaseEntityType >
  63. class PaintPowerUser : public BaseEntityType, public IPaintPowerUser
  64. {
  65. DECLARE_CLASS( PaintPowerUser< BaseEntityType >, BaseEntityType );
  66. #if defined( CLIENT_DLL ) && !defined( NO_ENTITY_PREDICTION )
  67. DECLARE_PREDICTABLE();
  68. static const datamap_t PredMapInit();
  69. #endif
  70. public:
  71. //-------------------------------------------------------------------------
  72. // Constructor/Virtual Destructor
  73. //-------------------------------------------------------------------------
  74. PaintPowerUser();
  75. virtual ~PaintPowerUser();
  76. //-------------------------------------------------------------------------
  77. // Public Accessors
  78. //-------------------------------------------------------------------------
  79. virtual const PaintPowerConstRange GetPaintPowers() const;
  80. virtual const PaintPowerInfo_t& GetPaintPower( unsigned powerType ) const;
  81. virtual const PaintPowerInfo_t* FindHighestPriorityActivePaintPower() const;
  82. //-------------------------------------------------------------------------
  83. // Paint Power Effects
  84. //-------------------------------------------------------------------------
  85. virtual void AddSurfacePaintPowerInfo( const PaintPowerInfo_t& contact, char const* context /*= 0*/ );
  86. virtual void UpdatePaintPowers();
  87. //-------------------------------------------------------------------------
  88. // Protected Types
  89. //-------------------------------------------------------------------------
  90. typedef CUtlVector< PaintPowerInfo_t > PaintPowerInfoVector;
  91. virtual void ChooseActivePaintPowers( PaintPowerInfoVector& activePowers ) = 0; // Default provided
  92. void ClearSurfacePaintPowerInfo();
  93. protected:
  94. //-------------------------------------------------------------------------
  95. // Paint Power Effects
  96. //-------------------------------------------------------------------------
  97. typedef int (*PaintPowerInfoCompare)( const PaintPowerInfo_t*, const PaintPowerInfo_t* );
  98. void PrioritySortSurfacePaintPowerInfo( PaintPowerInfoCompare comp );
  99. PaintPowerState ActivatePaintPower( PaintPowerInfo_t& power );
  100. PaintPowerState UsePaintPower( PaintPowerInfo_t& power );
  101. PaintPowerState DeactivatePaintPower( PaintPowerInfo_t& power );
  102. void MapSurfacesToPowers();
  103. bool SurfaceInfoContainsPower( const PaintPowerInfo_t& power, char const* context = 0 ) const;
  104. //-------------------------------------------------------------------------
  105. // Protected Accessors
  106. //-------------------------------------------------------------------------
  107. const PaintPowerConstRange GetSurfacePaintPowerInfo( char const* context = 0 ) const;
  108. bool HasAnySurfacePaintPowerInfo() const;
  109. //-------------------------------------------------------------------------
  110. // Protected Mutators
  111. //-------------------------------------------------------------------------
  112. void ForceSetPaintPower( const PaintPowerInfo_t& powerInfo );
  113. void ForcePaintPowerToState( PaintPowerType type, PaintPowerState newState );
  114. private:
  115. //-------------------------------------------------------------------------
  116. // Private Types
  117. //-------------------------------------------------------------------------
  118. struct ContextSurfacePaintPowerInfo_t
  119. {
  120. PaintPowerInfoVector paintPowerInfo;
  121. string_t context;
  122. };
  123. typedef CUtlVector< ContextSurfacePaintPowerInfo_t > ContextPaintPowerInfoArray;
  124. //-------------------------------------------------------------------------
  125. // Private Data
  126. //-------------------------------------------------------------------------
  127. PaintPowerInfo_t m_PaintPowers[PAINT_POWER_TYPE_COUNT_PLUS_NO_POWER]; // Current powers and their states
  128. PaintPowerInfoVector m_SurfacePaintPowerInfo; // Array of paint power info from surfaces touched
  129. ContextPaintPowerInfoArray m_ContextSurfacePaintPowerInfo; // Array of paint power info from surfaces under some context
  130. //-------------------------------------------------------------------------
  131. // Private Accessors
  132. //-------------------------------------------------------------------------
  133. const PaintPowerRange GetNonConstSurfacePaintPowerInfo( char const* context = 0 );
  134. int FindContextSurfacePaintPowerInfo( char const* context ) const;
  135. //-------------------------------------------------------------------------
  136. // Paint Power Effects
  137. //-------------------------------------------------------------------------
  138. virtual PaintPowerState ActivateSpeedPower( PaintPowerInfo_t& powerInfo ) = 0;
  139. virtual PaintPowerState UseSpeedPower( PaintPowerInfo_t& powerInfo ) = 0;
  140. virtual PaintPowerState DeactivateSpeedPower( PaintPowerInfo_t& powerInfo ) = 0;
  141. virtual PaintPowerState ActivateBouncePower( PaintPowerInfo_t& powerInfo ) = 0;
  142. virtual PaintPowerState UseBouncePower( PaintPowerInfo_t& powerInfo ) = 0;
  143. virtual PaintPowerState DeactivateBouncePower( PaintPowerInfo_t& powerInfo ) = 0;
  144. virtual PaintPowerState ActivateNoPower( PaintPowerInfo_t& powerInfo );
  145. virtual PaintPowerState UseNoPower( PaintPowerInfo_t& powerInfo );
  146. virtual PaintPowerState DeactivateNoPower( PaintPowerInfo_t& powerInfo );
  147. };
  148. //=============================================================================
  149. // PaintPowerUser Implementation
  150. //=============================================================================
  151. //#define DEFINE_PRED_TYPEDESCRIPTION( name, fieldtype ) \
  152. // { FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, NULL, NULL, NULL, &fieldtype::m_PredMap }
  153. // OMFG HACK: A macro to individually add embedded types from arrays because the current macros don't handle arrays of embedded types properly
  154. // OMFG TODO: Write a generic macro to work with templatized classes.
  155. #define DEFINE_EMBEDDED_ARRAY_ELEMENT( elementType, arrayName, arrayIndex ) \
  156. { FIELD_EMBEDDED, #arrayName"["#arrayIndex"]", offsetof(classNameTypedef, arrayName[arrayIndex]), 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, NULL, NULL, NULL, &elementType::m_PredMap }
  157. // OMFG HACK: Define the prediction table. The current macros don't work with templatized classes.
  158. // OMFG TODO: Write a generic macro to work with templatized classes.
  159. #if defined( CLIENT_DLL ) && !defined( NO_ENTITY_PREDICTION )
  160. template< typename BaseEntityType >
  161. datamap_t PaintPowerUser<BaseEntityType>::m_PredMap = PaintPowerUser<BaseEntityType>::PredMapInit();
  162. // Note: This type description table is unused but declared as part of DECLARE_PREDICTABLE. Initializing it here to get rid of warnings.
  163. template< typename BaseEntityType >
  164. typedescription_t PaintPowerUser<BaseEntityType>::m_PredDesc[1] = { { FIELD_VOID,0,0,0,0,0,0,0,0 } };
  165. template< typename BaseEntityType >
  166. datamap_t *PaintPowerUser<BaseEntityType>::GetPredDescMap( void )
  167. {
  168. return &m_PredMap;
  169. }
  170. template< typename BaseEntityType >
  171. const datamap_t PaintPowerUser<BaseEntityType>::PredMapInit()
  172. {
  173. typedef PaintPowerUser<BaseEntityType> classNameTypedef;
  174. static typedescription_t predDesc[] =
  175. {
  176. //{ FIELD_VOID,0,0,0,0,0,0,0,0 },
  177. //DEFINE_EMBEDDED_AUTO_ARRAY( m_PaintPowers ) // This only predicts the first element of the array right now
  178. DEFINE_EMBEDDED_ARRAY_ELEMENT( PaintPowerInfo_t, m_PaintPowers, BOUNCE_POWER ),
  179. DEFINE_EMBEDDED_ARRAY_ELEMENT( PaintPowerInfo_t, m_PaintPowers, SPEED_POWER ),
  180. DEFINE_EMBEDDED_ARRAY_ELEMENT( PaintPowerInfo_t, m_PaintPowers, NO_POWER )
  181. };
  182. datamap_t predMap = { predDesc, ARRAYSIZE( predDesc ), PAINT_POWER_USER_DATA_CLASS_NAME, &PaintPowerUser<BaseEntityType>::BaseClass::m_PredMap };
  183. return predMap;
  184. }
  185. #endif // if defined( CLIENT_DLL ) && !defined( NO_ENTITY_PREDICTION )
  186. template< typename BaseEntityType >
  187. PaintPowerUser<BaseEntityType>::PaintPowerUser()
  188. {
  189. for( unsigned i = 0; i < PAINT_POWER_TYPE_COUNT_PLUS_NO_POWER; ++i )
  190. {
  191. m_PaintPowers[i] = PaintPowerInfo_t();
  192. m_PaintPowers[i].m_State = INACTIVE_PAINT_POWER;
  193. }
  194. }
  195. template< typename BaseEntityType >
  196. PaintPowerUser<BaseEntityType>::~PaintPowerUser()
  197. {
  198. }
  199. template< typename BaseEntityType >
  200. const PaintPowerConstRange PaintPowerUser<BaseEntityType>::GetPaintPowers() const
  201. {
  202. return PaintPowerConstRange( m_PaintPowers, m_PaintPowers + ARRAYSIZE(m_PaintPowers) );
  203. }
  204. template< typename BaseEntityType >
  205. const PaintPowerInfo_t& PaintPowerUser<BaseEntityType>::GetPaintPower( unsigned powerType ) const
  206. {
  207. AssertMsg( powerType < PAINT_POWER_TYPE_COUNT_PLUS_NO_POWER, "Out of bounds." );
  208. return m_PaintPowers[ powerType < PAINT_POWER_TYPE_COUNT_PLUS_NO_POWER ? powerType : NO_POWER ];
  209. }
  210. template< typename BaseEntityType >
  211. const PaintPowerInfo_t* PaintPowerUser<BaseEntityType>::FindHighestPriorityActivePaintPower() const
  212. {
  213. const PaintPowerInfo_t* pPower = 0;
  214. for( unsigned i = 0; i < PAINT_POWER_TYPE_COUNT_PLUS_NO_POWER; ++i )
  215. {
  216. if( m_PaintPowers[i].m_State == ACTIVE_PAINT_POWER )
  217. {
  218. pPower = m_PaintPowers + i;
  219. break;
  220. }
  221. }
  222. return pPower;
  223. }
  224. template< typename BaseEntityType >
  225. void PaintPowerUser<BaseEntityType>::AddSurfacePaintPowerInfo( const PaintPowerInfo_t& contact, char const* context )
  226. {
  227. if ( !engine->HasPaintmap() )
  228. {
  229. Warning( "MEMORY LEAK: adding surface paint powers in a level with no paintmaps.\n" );
  230. return;
  231. }
  232. // If there's no context, add it to the default list
  233. if( context == NULL)
  234. {
  235. m_SurfacePaintPowerInfo.AddToTail( contact );
  236. }
  237. // There is a context, so add it to the appropriate list
  238. else
  239. {
  240. // Search for context
  241. int index = FindContextSurfacePaintPowerInfo( context );
  242. // If not found, create it first
  243. if( index == m_ContextSurfacePaintPowerInfo.InvalidIndex() )
  244. {
  245. index = m_ContextSurfacePaintPowerInfo.Count();
  246. m_ContextSurfacePaintPowerInfo.EnsureCount( index + 1 );
  247. m_ContextSurfacePaintPowerInfo[index].context = AllocPooledString( context );
  248. }
  249. // Add the new surface info
  250. m_ContextSurfacePaintPowerInfo[index].paintPowerInfo.AddToTail( contact );
  251. }
  252. }
  253. template< typename BaseEntityType >
  254. void PaintPowerUser<BaseEntityType>::ChooseActivePaintPowers( PaintPowerInfoVector& activePowers )
  255. {
  256. // Figure out colors/powers
  257. MapSurfacesToPowers();
  258. // If there is a contact with any surface
  259. if( m_SurfacePaintPowerInfo.Count() != 0 )
  260. {
  261. // Sort the surfaces by priority
  262. PrioritySortSurfacePaintPowerInfo( &DescendingPaintPriorityCompare );
  263. // The active power is the one with the highest priority
  264. activePowers.AddToTail( m_SurfacePaintPowerInfo.Head() );
  265. }
  266. }
  267. template< typename BaseEntityType >
  268. void PaintPowerUser<BaseEntityType>::UpdatePaintPowers()
  269. {
  270. // Only update if there's paint in the map
  271. if( engine->HasPaintmap() )
  272. {
  273. // Update which powers are active
  274. PaintPowerInfoVector activePowers;
  275. ChooseActivePaintPowers( activePowers );
  276. // Cache the powers
  277. PaintPowerInfo_t cachedPowers[PAINT_POWER_TYPE_COUNT_PLUS_NO_POWER];
  278. //V_memcpy( cachedPowers, m_PaintPowers, sizeof(PaintPowerInfo_t) * PAINT_POWER_TYPE_COUNT_PLUS_NO_POWER );
  279. std::copy( m_PaintPowers, m_PaintPowers + PAINT_POWER_TYPE_COUNT_PLUS_NO_POWER, cachedPowers );
  280. // Set all powers in a state other than inactive to deactivating
  281. for( unsigned i = 0; i < PAINT_POWER_TYPE_COUNT_PLUS_NO_POWER; ++i )
  282. {
  283. PaintPowerInfo_t& power = m_PaintPowers[i];
  284. power.m_State = IsInactivePower( power ) ? INACTIVE_PAINT_POWER : DEACTIVATING_PAINT_POWER;
  285. }
  286. // For each new active power
  287. PaintPowerConstRange activeRange = GetConstRange( activePowers );
  288. for( PaintPowerConstIter i = activeRange.first; i != activeRange.second; ++i )
  289. {
  290. // Set it as the current one
  291. const PaintPowerInfo_t& newPower = *i;
  292. const unsigned index = newPower.m_PaintPowerType;
  293. m_PaintPowers[index] = newPower;
  294. // If the old power was active and roughly the same, keep it active. Otherwise, activate it.
  295. const PaintPowerInfo_t& oldPower = cachedPowers[index];
  296. const bool stayActive = IsActivePower( oldPower ) && AreSamePower( oldPower, newPower );
  297. m_PaintPowers[index].m_State = stayActive ? ACTIVE_PAINT_POWER : ACTIVATING_PAINT_POWER;
  298. }
  299. // Clear the surface information
  300. // NOTE: Calling this after Activating/Using/Deactivating paint powers makes sticky boxes not very sticky
  301. // and that's why I moved it back over here. -Brett
  302. ClearSurfacePaintPowerInfo();
  303. // Update the state of each power
  304. for( unsigned i = 0; i < PAINT_POWER_TYPE_COUNT_PLUS_NO_POWER; ++i )
  305. {
  306. switch( m_PaintPowers[i].m_State )
  307. {
  308. case ACTIVATING_PAINT_POWER:
  309. m_PaintPowers[i].m_State = ActivatePaintPower( m_PaintPowers[i] );
  310. #if defined CLIENT_DLL
  311. RANDOM_CEG_TEST_SECRET_PERIOD( 127, 1023 );
  312. #endif
  313. break;
  314. case ACTIVE_PAINT_POWER:
  315. m_PaintPowers[i].m_State = UsePaintPower( m_PaintPowers[i] );
  316. break;
  317. case DEACTIVATING_PAINT_POWER:
  318. #if defined GAME_DLL
  319. RANDOM_CEG_TEST_SECRET_PERIOD( 937, 3821 );
  320. #endif
  321. m_PaintPowers[i].m_State = DeactivatePaintPower( m_PaintPowers[i] );
  322. break;
  323. }
  324. }
  325. }
  326. }
  327. template< typename BaseEntityType >
  328. void PaintPowerUser<BaseEntityType>::ClearSurfacePaintPowerInfo()
  329. {
  330. m_SurfacePaintPowerInfo.RemoveAll();
  331. const int count = m_ContextSurfacePaintPowerInfo.Count();
  332. for( int i = 0; i < count; ++i )
  333. {
  334. m_ContextSurfacePaintPowerInfo[i].paintPowerInfo.RemoveAll();
  335. }
  336. }
  337. template< typename BaseEntityType >
  338. void PaintPowerUser<BaseEntityType>::PrioritySortSurfacePaintPowerInfo( PaintPowerInfoCompare comp )
  339. {
  340. // Sort the surfaces by priority
  341. m_SurfacePaintPowerInfo.Sort( comp );
  342. const int count = m_ContextSurfacePaintPowerInfo.Count();
  343. for( int i = 0; i < count; ++i )
  344. {
  345. m_ContextSurfacePaintPowerInfo[i].paintPowerInfo.Sort( comp );
  346. }
  347. }
  348. template< typename PaintPowerIterator >
  349. void MapSurfacesToPowers( PaintPowerIterator begin, PaintPowerIterator end )
  350. {
  351. for( PaintPowerIterator i = begin; i != end; ++i )
  352. {
  353. MapSurfaceToPower(*i);
  354. }
  355. }
  356. template< typename BaseEntityType >
  357. void PaintPowerUser<BaseEntityType>::MapSurfacesToPowers()
  358. {
  359. PaintPowerRange range = GetNonConstSurfacePaintPowerInfo();
  360. ::MapSurfacesToPowers( range.first, range.second );
  361. const int count = m_ContextSurfacePaintPowerInfo.Count();
  362. for( int i = 0; i < count; ++i )
  363. {
  364. PaintPowerRange contextRange = GetRange( m_ContextSurfacePaintPowerInfo[i].paintPowerInfo );
  365. ::MapSurfacesToPowers( contextRange.first, contextRange.second );
  366. }
  367. }
  368. template< typename BaseEntityType >
  369. bool PaintPowerUser<BaseEntityType>::SurfaceInfoContainsPower( const PaintPowerInfo_t& power, char const* context ) const
  370. {
  371. PaintPowerConstRange range = GetSurfacePaintPowerInfo( context );
  372. for( PaintPowerConstIter i = range.first; i != range.second; ++i )
  373. {
  374. if( AreSamePower(power, *i) )
  375. return true;
  376. }
  377. return false;
  378. }
  379. template< typename BaseEntityType >
  380. const PaintPowerRange PaintPowerUser<BaseEntityType>::GetNonConstSurfacePaintPowerInfo( char const* context )
  381. {
  382. if( !context )
  383. return GetRange( m_SurfacePaintPowerInfo );
  384. const int i = FindContextSurfacePaintPowerInfo( context );
  385. #ifdef PAINT_POWER_USER_DEBUG
  386. if( i == m_ContextSurfacePaintPowerInfo.InvalidIndex() )
  387. Warning( "Trying to get a range that doesn't exist.\n" );
  388. #endif
  389. return i != m_ContextSurfacePaintPowerInfo.InvalidIndex() ? GetRange( m_ContextSurfacePaintPowerInfo[i].paintPowerInfo ) : PaintPowerRange( (PaintPowerIter)0, (PaintPowerIter)0 );
  390. }
  391. template< typename BaseEntityType >
  392. int PaintPowerUser<BaseEntityType>::FindContextSurfacePaintPowerInfo( char const* context ) const
  393. {
  394. AssertMsg( context, "Null pointers are bad, and you should feel bad." );
  395. int index = m_ContextSurfacePaintPowerInfo.InvalidIndex();
  396. const int count = m_ContextSurfacePaintPowerInfo.Count();
  397. for( int i = 0; i < count; ++i )
  398. {
  399. if( !V_strncmp( STRING( m_ContextSurfacePaintPowerInfo[i].context ), context, MAX_PAINT_SURFACE_CONTEXT_LENGTH ) )
  400. {
  401. index = i;
  402. break;
  403. }
  404. }
  405. return index;
  406. }
  407. template< typename BaseEntityType >
  408. PaintPowerState PaintPowerUser<BaseEntityType>::ActivatePaintPower( PaintPowerInfo_t& power )
  409. {
  410. AssertMsg( power.m_State == ACTIVATING_PAINT_POWER, "Activating a paint power that's not trying to activate." );
  411. switch( power.m_PaintPowerType )
  412. {
  413. case BOUNCE_POWER:
  414. return ActivateBouncePower( power );
  415. case SPEED_POWER:
  416. return ActivateSpeedPower( power );
  417. case PORTAL_POWER:
  418. return ActivateNoPower( power );
  419. case REFLECT_POWER:
  420. return ActivateNoPower( power );
  421. case NO_POWER:
  422. return ActivateNoPower( power );
  423. default:
  424. AssertMsg( false, "Invalid power or power hasn't been added to PaintPowerUser properly." );
  425. return INACTIVE_PAINT_POWER;
  426. }
  427. }
  428. template< typename BaseEntityType >
  429. PaintPowerState PaintPowerUser<BaseEntityType>::UsePaintPower( PaintPowerInfo_t& power )
  430. {
  431. AssertMsg( power.m_State == ACTIVE_PAINT_POWER, "Using a power that hasn't been activated." );
  432. switch( power.m_PaintPowerType )
  433. {
  434. case BOUNCE_POWER:
  435. return UseBouncePower( power );
  436. case SPEED_POWER:
  437. return UseSpeedPower( power );
  438. case PORTAL_POWER:
  439. return UseNoPower( power );
  440. case REFLECT_POWER:
  441. return UseNoPower( power );
  442. case NO_POWER:
  443. return UseNoPower( power );
  444. default:
  445. AssertMsg( false, "Invalid power or power hasn't been added to PaintPowerUser properly." );
  446. return INACTIVE_PAINT_POWER;
  447. }
  448. }
  449. template< typename BaseEntityType >
  450. PaintPowerState PaintPowerUser<BaseEntityType>::DeactivatePaintPower( PaintPowerInfo_t& power )
  451. {
  452. AssertMsg( power.m_State == DEACTIVATING_PAINT_POWER, "Deactivating a power that's not trying to deactivate." );
  453. switch( power.m_PaintPowerType )
  454. {
  455. case BOUNCE_POWER:
  456. return DeactivateBouncePower( power );
  457. case SPEED_POWER:
  458. return DeactivateSpeedPower( power );
  459. case PORTAL_POWER:
  460. return DeactivateNoPower( power );
  461. case REFLECT_POWER:
  462. return DeactivateNoPower( power );
  463. case NO_POWER:
  464. return DeactivateNoPower( power );
  465. default:
  466. AssertMsg( false, "Invalid power or power hasn't been added to PaintPowerUser properly." );
  467. return INACTIVE_PAINT_POWER;
  468. }
  469. }
  470. template< typename BaseEntityType >
  471. const PaintPowerConstRange PaintPowerUser<BaseEntityType>::GetSurfacePaintPowerInfo( char const* context ) const
  472. {
  473. if( !context )
  474. return GetConstRange( m_SurfacePaintPowerInfo );
  475. const int i = FindContextSurfacePaintPowerInfo( context );
  476. #ifdef PAINT_POWER_USER_DEBUG
  477. if( i == m_ContextSurfacePaintPowerInfo.InvalidIndex() )
  478. Warning( "Trying to get a range that doesn't exist.\n" );
  479. #endif
  480. return i != m_ContextSurfacePaintPowerInfo.InvalidIndex() ? GetConstRange( m_ContextSurfacePaintPowerInfo[i].paintPowerInfo ) : PaintPowerConstRange( (PaintPowerConstIter)0, (PaintPowerConstIter)0 );
  481. }
  482. template< typename BaseEntityType >
  483. bool PaintPowerUser<BaseEntityType>::HasAnySurfacePaintPowerInfo() const
  484. {
  485. bool hasSurfaceInfo = m_SurfacePaintPowerInfo.Count() != 0;
  486. const int count = m_ContextSurfacePaintPowerInfo.Count();
  487. for( int i = 0; i < count && !hasSurfaceInfo; ++i )
  488. {
  489. hasSurfaceInfo = m_ContextSurfacePaintPowerInfo[i].paintPowerInfo.Count() != 0;
  490. }
  491. return hasSurfaceInfo;
  492. }
  493. template< typename BaseEntityType >
  494. void PaintPowerUser<BaseEntityType>::ForceSetPaintPower( const PaintPowerInfo_t& powerInfo )
  495. {
  496. m_PaintPowers[powerInfo.m_PaintPowerType] = powerInfo;
  497. }
  498. template< typename BaseEntityType >
  499. void PaintPowerUser<BaseEntityType>::ForcePaintPowerToState( PaintPowerType type, PaintPowerState newState )
  500. {
  501. // TODO: Implement some error checking for edge cases here.
  502. m_PaintPowers[type].m_State = newState;
  503. }
  504. template< typename BaseEntityType >
  505. PaintPowerState PaintPowerUser<BaseEntityType>::ActivateNoPower( PaintPowerInfo_t& powerInfo )
  506. {
  507. return ACTIVE_PAINT_POWER;
  508. }
  509. template< typename BaseEntityType >
  510. PaintPowerState PaintPowerUser<BaseEntityType>::UseNoPower( PaintPowerInfo_t& powerInfo )
  511. {
  512. return ACTIVE_PAINT_POWER;
  513. }
  514. template< typename BaseEntityType >
  515. PaintPowerState PaintPowerUser<BaseEntityType>::DeactivateNoPower( PaintPowerInfo_t& powerInfo )
  516. {
  517. return INACTIVE_PAINT_POWER;
  518. }
  519. #endif // ifndef PAINT_POWER_USER_H