/* ** Command & Conquer Generals(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ //////////////////////////////////////////////////////////////////////////////// // // // (c) 2001-2003 Electronic Arts Inc. // // // //////////////////////////////////////////////////////////////////////////////// // FILE: SpecialPower.h /////////////////////////////////////////////////////////////////////////// // Author: Colin Day, April 2002 // Desc: Special power templates and the system that holds them // Edited: Kris Morness -- July 2002 (added BitFlag system) /////////////////////////////////////////////////////////////////////////////////////////////////// #pragma once #ifndef __SPECIALPOWER_H_ #define __SPECIALPOWER_H_ // USER INCLUDES ////////////////////////////////////////////////////////////////////////////////// #include "Common/AudioEventRTS.h" #include "Common/GameMemory.h" #include "Common/SubsystemInterface.h" #include "Lib/BaseType.h" #include "Common/BitFlags.h" #include "Common/Overridable.h" #include "Common/Override.h" // FORWARD REFERENCES ///////////////////////////////////////////////////////////////////////////// class ObjectCreationList; class Object; enum ScienceType; struct FieldParse; // For SpecialPowerType and SpecialPowerMaskType::s_bitNameList. Part of detangling. #include "Common/SpecialPowerType.h" // For SpecialPowerMaskType. Part of detangling. #include "Common/SpecialPowerMaskType.h" #define MAKE_SPECIALPOWER_MASK(k) SpecialPowerMaskType(SpecialPowerMaskType::kInit, (k)) inline Bool TEST_SPECIALPOWERMASK(const SpecialPowerMaskType& m, SpecialPowerType t) { return m.test(t); } inline Bool TEST_SPECIALPOWERMASK_ANY(const SpecialPowerMaskType& m, const SpecialPowerMaskType& mask) { return m.anyIntersectionWith(mask); } inline Bool TEST_SPECIALPOWERMASK_MULTI(const SpecialPowerMaskType& m, const SpecialPowerMaskType& mustBeSet, const SpecialPowerMaskType& mustBeClear) { return m.testSetAndClear(mustBeSet, mustBeClear); } inline Bool SPECIALPOWERMASK_ANY_SET(const SpecialPowerMaskType& m) { return m.any(); } inline void CLEAR_SPECIALPOWERMASK(SpecialPowerMaskType& m) { m.clear(); } inline void SET_SPECIALPOWERMASK( SpecialPowerMaskType& m, SpecialPowerType t, Int val = 1 ) { m.set( t, val ); } inline void SET_ALL_SPECIALPOWERMASK_BITS(SpecialPowerMaskType& m) { m.clear(); m.flip(); } inline void FLIP_SPECIALPOWERMASK(SpecialPowerMaskType& m) { m.flip(); } //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- class SpecialPowerTemplate : public Overridable { MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( SpecialPowerTemplate, "SpecialPowerTemplate" ) public: SpecialPowerTemplate(); // virtual destructor prototype provided by MemoryPoolObject static const FieldParse* getFieldParse( void ) { return m_specialPowerFieldParse; } void friend_setNameAndID(const AsciiString& name, UnsignedInt id) { m_name = name; m_id = id; } AsciiString getName( void ) const { return getFO()->m_name; } UnsignedInt getID( void ) const { return getFO()->m_id; } SpecialPowerType getSpecialPowerType( void ) const { return getFO()->m_type; } UnsignedInt getReloadTime( void ) const { return getFO()->m_reloadTime; } ScienceType getRequiredScience( void ) const { return getFO()->m_requiredScience; } const AudioEventRTS *getInitiateSound( void ) const { return &getFO()->m_initiateSound; } const AudioEventRTS *getInitiateAtTargetSound( void ) const { return &getFO()->m_initiateAtLocationSound; } Bool hasPublicTimer( void ) const { return getFO()->m_publicTimer; } Bool isSharedNSync( void ) const { return getFO()->m_sharedNSync; } UnsignedInt getDetectionTime( void ) const { return getFO()->m_detectionTime; } UnsignedInt getViewObjectDuration( void ) const { return getFO()->m_viewObjectDuration; } Real getViewObjectRange( void ) const { return getFO()->m_viewObjectRange; } Real getRadiusCursorRadius() const { return getFO()->m_radiusCursorRadius; } private: const SpecialPowerTemplate* getFO() const { return (const SpecialPowerTemplate*)friend_getFinalOverride(); } AsciiString m_name; ///< name UnsignedInt m_id; ///< unique identifier SpecialPowerType m_type; ///< enum allowing for fast type checking for ability processing. UnsignedInt m_reloadTime; ///< (frames) after using special power, how long it takes to use again ScienceType m_requiredScience; ///< science required (if any) to actually execute this power AudioEventRTS m_initiateSound; ///< sound to play when initiated AudioEventRTS m_initiateAtLocationSound; ///< sound to play at target location (if any) UnsignedInt m_detectionTime; ///< (frames) after using infiltration power (defection, etc.), ///< how long it takes for ex comrades to realize it on their own UnsignedInt m_viewObjectDuration; ///< Lifetime of a looking object we slap down so you can watch the effect Real m_viewObjectRange; ///< And how far that object can see. Real m_radiusCursorRadius; ///< size of radius cursor, if any Bool m_publicTimer; ///< display a countdown timer for this special power for all to see Bool m_sharedNSync; ///< If true, this is a special that is shared between all of a player's command centers static const FieldParse m_specialPowerFieldParse[]; ///< the parse table }; //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- class SpecialPowerStore : public SubsystemInterface { public: SpecialPowerStore( void ); ~SpecialPowerStore( void ); virtual void init( void ) { }; virtual void update( void ) { }; virtual void reset( void ); const SpecialPowerTemplate *findSpecialPowerTemplate( AsciiString name ) { return findSpecialPowerTemplatePrivate(name); } const SpecialPowerTemplate *findSpecialPowerTemplateByID( UnsignedInt id ); const SpecialPowerTemplate *getSpecialPowerTemplateByIndex( UnsignedInt index ); // for WorldBuilder /// does the object (and therefore the player) meet all the requirements to use this power Bool canUseSpecialPower( Object *obj, const SpecialPowerTemplate *specialPowerTemplate ); Int getNumSpecialPowers( void ); // for WorldBuilder static void parseSpecialPowerDefinition( INI *ini ); private: protected: SpecialPowerTemplate *findSpecialPowerTemplatePrivate( AsciiString name ); typedef std::vector SpecialPowerTemplatePtrVector; SpecialPowerTemplatePtrVector m_specialPowerTemplates; ///< the special power templates UnsignedInt m_nextSpecialPowerID; }; // EXTERNAL /////////////////////////////////////////////////////////////////////////////////////// extern SpecialPowerStore *TheSpecialPowerStore; #endif // end __SPECIALPOWER_H_