ThingTemplate.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: ThingTemplate.h //////////////////////////////////////////////////////////////////////////
  24. // Author: Colin Day, April 2001
  25. // Desc: Thing templates are a 'roadmap' to creating things
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. #pragma once
  28. #ifndef __THINGTEMPLATE_H_
  29. #define __THINGTEMPLATE_H_
  30. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  31. #include "Lib/BaseType.h"
  32. #include "Common/AudioEventRTS.h"
  33. #include "Common/FileSystem.h"
  34. #include "Common/GameCommon.h"
  35. #include "Common/Geometry.h"
  36. #include "Common/KindOf.h"
  37. #include "Common/ModuleFactory.h"
  38. #include "Common/Overridable.h"
  39. #include "Common/ProductionPrerequisite.h"
  40. #include "Common/Science.h"
  41. #include "Common/UnicodeString.h"
  42. #include "GameLogic/ArmorSet.h"
  43. #include "GameLogic/WeaponSet.h"
  44. #include "Common/STLTypedefs.h"
  45. #include "GameClient/Color.h"
  46. // FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
  47. class AIUpdateModuleData;
  48. class Image;
  49. class Object;
  50. class Drawable;
  51. class ProductionPrerequisite;
  52. struct FieldParse;
  53. class Player;
  54. class INI;
  55. enum RadarPriorityType;
  56. enum ScienceType;
  57. enum EditorSortingType;
  58. enum ShadowType;
  59. class WeaponTemplateSet;
  60. class ArmorTemplateSet;
  61. class FXList;
  62. // TYPEDEFS FOR FILE //////////////////////////////////////////////////////////////////////////////
  63. typedef std::map<AsciiString, AudioEventRTS> PerUnitSoundMap;
  64. typedef std::map<AsciiString, const FXList*> PerUnitFXMap;
  65. //-------------------------------------------------------------------------------------------------
  66. //-------------------------------------------------------------------------------------------------
  67. //Code renderer handles these states now.
  68. //enum InventoryImageType
  69. //{
  70. // INV_IMAGE_ENABLED = 0,
  71. // INV_IMAGE_DISABLED,
  72. // INV_IMAGE_HILITE,
  73. // INV_IMAGE_PUSHED,
  74. //
  75. // INV_IMAGE_NUM_IMAGES // keep this last
  76. //
  77. //};
  78. //-------------------------------------------------------------------------------------------------
  79. //-------------------------------------------------------------------------------------------------
  80. enum
  81. {
  82. MAX_UPGRADE_CAMEO_UPGRADES = 5
  83. };
  84. //-------------------------------------------------------------------------------------------------
  85. //-------------------------------------------------------------------------------------------------
  86. enum ThingTemplateAudioType
  87. {
  88. TTAUDIO_voiceSelect, ///< Response when unit is selected
  89. TTAUDIO_voiceGroupSelect, ///< Response when a group of this unit is selected
  90. TTAUDIO_voiceSelectElite, ///< Response when unit is selected and elite
  91. TTAUDIO_voiceMove, ///< Response when unit moves
  92. TTAUDIO_voiceAttack, ///< Response when unit is told to attack
  93. TTAUDIO_voiceEnter, ///< Response when unit is told to enter a building
  94. TTAUDIO_voiceFear, ///< Response when unit is under attack
  95. TTAUDIO_voiceCreated, ///< Response when unit is created
  96. TTAUDIO_voiceNearEnemy, ///< Unit is near an enemy
  97. TTAUDIO_voiceTaskUnable, ///< Unit is told to do something impossible
  98. TTAUDIO_voiceTaskComplete, ///< Unit completes a move, or other task indicated
  99. TTAUDIO_voiceMeetEnemy, ///< Unit meets an enemy unit
  100. TTAUDIO_soundMoveStart, ///< Sound when unit starts moving
  101. TTAUDIO_soundMoveStartDamaged, ///< Sound when unit starts moving and is damaged
  102. TTAUDIO_soundMoveLoop, ///< Sound when unit is moving
  103. TTAUDIO_soundMoveLoopDamaged, ///< Sound when unit is moving and is damaged
  104. TTAUDIO_soundAmbient, ///< Ambient sound for unit during normal status. Also the default sound
  105. TTAUDIO_soundAmbientDamaged, ///< Ambient sound for unit if damaged. Corresponds to body info damage
  106. TTAUDIO_soundAmbientReallyDamaged,///< Ambient sound for unit if badly damaged.
  107. TTAUDIO_soundAmbientRubble, ///< Ambient sound for unit if it is currently rubble. (Dam, for instance)
  108. TTAUDIO_soundStealthOn, ///< Sound when unit stealths
  109. TTAUDIO_soundStealthOff, ///< Sound when unit destealths
  110. TTAUDIO_soundCreated, ///< Sound when unit is created
  111. TTAUDIO_soundOnDamaged, ///< Sound when unit enters damaged state
  112. TTAUDIO_soundOnReallyDamaged, ///< Sound when unit enters reallyd damaged state
  113. TTAUDIO_soundEnter, ///< Sound when another unit enters me.
  114. TTAUDIO_soundExit, ///< Sound when another unit exits me.
  115. TTAUDIO_soundPromotedVeteran, ///< Sound when unit gets promoted to Veteran level
  116. TTAUDIO_soundPromotedElite, ///< Sound when unit gets promoted to Elite level
  117. TTAUDIO_soundPromotedHero, ///< Sound when unit gets promoted to Hero level
  118. TTAUDIO_voiceGarrison, ///< Unit is ordered to enter a garrisonable building
  119. TTAUDIO_soundFalling, ///< This sound is actually called on a unit when it is exiting another.
  120. ///< However, there is a soundExit which refers to the container, and this is only used for bombs falling from planes.
  121. #ifdef ALLOW_SURRENDER
  122. TTAUDIO_voiceSurrender, ///< Unit surrenders
  123. #endif
  124. TTAUDIO_voiceDefect, ///< Unit is forced to defect
  125. TTAUDIO_voiceAttackSpecial, ///< Unit is ordered to use a special attack
  126. TTAUDIO_voiceAttackAir, ///< Unit is ordered to attack an airborne unit
  127. TTAUDIO_voiceGuard, ///< Unit is ordered to guard an area
  128. TTAUDIO_COUNT // keep last!
  129. };
  130. class AudioArray
  131. {
  132. public:
  133. DynamicAudioEventRTS* m_audio[TTAUDIO_COUNT];
  134. AudioArray()
  135. {
  136. for (Int i = 0; i < TTAUDIO_COUNT; ++i)
  137. m_audio[i] = NULL;
  138. }
  139. ~AudioArray()
  140. {
  141. for (Int i = 0; i < TTAUDIO_COUNT; ++i)
  142. if (m_audio[i])
  143. m_audio[i]->deleteInstance();
  144. }
  145. AudioArray(const AudioArray& that)
  146. {
  147. for (Int i = 0; i < TTAUDIO_COUNT; ++i)
  148. {
  149. if (that.m_audio[i])
  150. m_audio[i] = newInstance(DynamicAudioEventRTS)(*that.m_audio[i]);
  151. else
  152. m_audio[i] = NULL;
  153. }
  154. }
  155. AudioArray& operator=(const AudioArray& that)
  156. {
  157. if (this != &that)
  158. {
  159. for (Int i = 0; i < TTAUDIO_COUNT; ++i)
  160. {
  161. if (that.m_audio[i])
  162. {
  163. if (m_audio[i])
  164. *m_audio[i] = *that.m_audio[i];
  165. else
  166. m_audio[i] = newInstance(DynamicAudioEventRTS)(*that.m_audio[i]);
  167. }
  168. else
  169. {
  170. m_audio[i] = NULL;
  171. }
  172. }
  173. }
  174. return *this;
  175. }
  176. };
  177. //-------------------------------------------------------------------------------------------------
  178. /** Object class type enumeration */
  179. //-------------------------------------------------------------------------------------------------
  180. enum BuildCompletionType
  181. {
  182. BC_INVALID = 0,
  183. BC_APPEARS_AT_RALLY_POINT, ///< unit appears at rally point of its #1 prereq
  184. BC_PLACED_BY_PLAYER, ///< unit must be manually placed by player
  185. BC_NUM_TYPES // leave this last
  186. };
  187. #ifdef DEFINE_BUILD_COMPLETION_NAMES
  188. static const char *BuildCompletionNames[] =
  189. {
  190. "INVALID",
  191. "APPEARS_AT_RALLY_POINT",
  192. "PLACED_BY_PLAYER",
  193. NULL
  194. };
  195. #endif // end DEFINE_BUILD_COMPLETION_NAMES
  196. enum BuildableStatus
  197. {
  198. // saved into savegames... do not change or remove values!
  199. BSTATUS_YES = 0,
  200. BSTATUS_IGNORE_PREREQUISITES,
  201. BSTATUS_NO,
  202. BSTATUS_ONLY_BY_AI,
  203. BSTATUS_NUM_TYPES // leave this last
  204. };
  205. #ifdef DEFINE_BUILDABLE_STATUS_NAMES
  206. static const char *BuildableStatusNames[] =
  207. {
  208. "Yes",
  209. "Ignore_Prerequisites",
  210. "No",
  211. "Only_By_AI",
  212. NULL
  213. };
  214. #endif // end DEFINE_BUILDABLE_STATUS_NAMES
  215. //-------------------------------------------------------------------------------------------------
  216. enum ModuleParseMode
  217. {
  218. MODULEPARSE_NORMAL,
  219. MODULEPARSE_ADD_REMOVE_REPLACE,
  220. MODULEPARSE_INHERITABLE,
  221. MODULEPARSE_OVERRIDEABLE_BY_LIKE_KIND,
  222. };
  223. //-------------------------------------------------------------------------------------------------
  224. class ModuleInfo
  225. {
  226. private:
  227. struct Nugget
  228. {
  229. AsciiString first;
  230. AsciiString m_moduleTag;
  231. const ModuleData* second;
  232. Int interfaceMask;
  233. Bool copiedFromDefault;
  234. Bool inheritable;
  235. Bool overrideableByLikeKind;
  236. Nugget(const AsciiString& n, const AsciiString& moduleTag, const ModuleData* d, Int i, Bool inh, Bool oblk)
  237. : first(n),
  238. m_moduleTag(moduleTag),
  239. second(d),
  240. interfaceMask(i),
  241. copiedFromDefault(false),
  242. inheritable(inh),
  243. overrideableByLikeKind(oblk)
  244. {
  245. }
  246. };
  247. std::vector<Nugget> m_info;
  248. public:
  249. ModuleInfo() { }
  250. void addModuleInfo( ThingTemplate *thingTemplate, const AsciiString& name, const AsciiString& moduleTag, const ModuleData* data, Int interfaceMask, Bool inheritable, Bool overrideableByLikeKind = FALSE );
  251. const ModuleInfo::Nugget *ModuleInfo::getNuggetWithTag( const AsciiString& tag ) const;
  252. Int getCount() const
  253. {
  254. return m_info.size();
  255. }
  256. #if defined(_DEBUG) || defined(_INTERNAL)
  257. Bool containsPartialName(const char* n) const
  258. {
  259. for (int i = 0; i < m_info.size(); i++)
  260. if (strstr(m_info[i].first.str(), n) != NULL)
  261. return true;
  262. return false;
  263. }
  264. #endif
  265. AsciiString getNthName(Int i) const
  266. {
  267. if (i >= 0 && i < m_info.size())
  268. {
  269. return m_info[i].first;
  270. }
  271. return AsciiString::TheEmptyString;
  272. }
  273. AsciiString getNthTag(Int i) const
  274. {
  275. if (i >= 0 && i < m_info.size())
  276. {
  277. return m_info[i].m_moduleTag;
  278. }
  279. return AsciiString::TheEmptyString;
  280. }
  281. const ModuleData* getNthData(Int i) const
  282. {
  283. if (i >= 0 && i < m_info.size())
  284. {
  285. return m_info[i].second;
  286. }
  287. return NULL;
  288. }
  289. // for use only by ThingTemplate::friend_getAIModuleInfo
  290. ModuleData* friend_getNthData(Int i);
  291. void clear()
  292. {
  293. m_info.clear();
  294. }
  295. void setCopiedFromDefault(Bool v)
  296. {
  297. for (int i = 0; i < m_info.size(); i++)
  298. m_info[i].copiedFromDefault = v;
  299. }
  300. Bool clearModuleDataWithTag(const AsciiString& tagToClear, AsciiString& clearedModuleNameOut);
  301. Bool clearCopiedFromDefaultEntries(Int interfaceMask, const AsciiString &name, const ThingTemplate *fullTemplate );
  302. Bool clearAiModuleInfo();
  303. };
  304. //-------------------------------------------------------------------------------------------------
  305. /** Definition of a thing template to read from our game data framework */
  306. //-------------------------------------------------------------------------------------------------
  307. class ThingTemplate : public Overridable
  308. {
  309. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(ThingTemplate, "ThingTemplatePool" )
  310. private:
  311. ThingTemplate(const ThingTemplate& that) : m_geometryInfo(that.m_geometryInfo)
  312. {
  313. DEBUG_CRASH(("This should never be called\n"));
  314. }
  315. public:
  316. ThingTemplate();
  317. // copy the guts of that into this, but preserve this' name, id, and list-links.
  318. void copyFrom(const ThingTemplate* that);
  319. /// called by ThingFactory after all templates have been loaded.
  320. void resolveNames();
  321. #ifdef LOAD_TEST_ASSETS
  322. void initForLTA(const AsciiString& name);
  323. inline AsciiString getLTAName() const { return m_LTAName; }
  324. #endif
  325. /**
  326. return a unique identifier suitable for identifying this ThingTemplate on machines playing
  327. across the net. this should be considered a Magic Cookie and used only for net traffic or
  328. similar sorts of things. To convert an id back to a ThingTemplate, use ThingFactory::findByID().
  329. Note that 0 is always an invalid id. NOTE that we are not referencing m_override here
  330. because even though we actually have multiple templates here representing overrides,
  331. we still only conceptually have one template and want to always use one single
  332. pointer for comparisons of templates. However, even if we did reference m_override
  333. the IDs would be the same for each one since every override first *COPIES* data
  334. from the current/parent template data.
  335. */
  336. UnsignedShort getTemplateID() const { return m_templateID; }
  337. // note that m_override is not used here, see getTemplateID(), for it is the same reasons
  338. const AsciiString& getName() const { return m_nameString; } ///< return the name of this template
  339. /// get the display color (used for the editor)
  340. Color getDisplayColor() const { return m_displayColor; }
  341. /// get the editor sorting
  342. EditorSortingType getEditorSorting() const { return (EditorSortingType)m_editorSorting; }
  343. /// return true iff the template has the specified kindOf flag set.
  344. inline Bool isKindOf(KindOfType t) const
  345. {
  346. return TEST_KINDOFMASK(m_kindof, t);
  347. }
  348. /// convenience for doing multiple kindof testing at once.
  349. inline Bool isKindOfMulti(const KindOfMaskType& mustBeSet, const KindOfMaskType& mustBeClear) const
  350. {
  351. return TEST_KINDOFMASK_MULTI(m_kindof, mustBeSet, mustBeClear);
  352. }
  353. inline Bool isAnyKindOf( const KindOfMaskType& anyKindOf ) const
  354. {
  355. return TEST_KINDOFMASK_ANY(m_kindof, anyKindOf);
  356. }
  357. /// set the display name
  358. const UnicodeString& getDisplayName() const { return m_displayName; } ///< return display name
  359. RadarPriorityType getDefaultRadarPriority() const { return (RadarPriorityType)m_radarPriority; } ///< return radar priority from INI
  360. // note, you should not call this directly; rather, call Object::getTransportSlotCount().
  361. Int getRawTransportSlotCount() const { return m_transportSlotCount; }
  362. Real getFenceWidth() const { return m_fenceWidth; } // return fence width
  363. Real getFenceXOffset() const { return m_fenceXOffset; } // return fence offset
  364. Bool isBridge() const { return m_isBridge; } // return fence offset
  365. // Only Object can ask this. Everyone else should ask the Object. In fact, you really should ask the Object everything.
  366. Real friend_calcVisionRange() const { return m_visionRange; } ///< get vision range
  367. Real friend_calcShroudClearingRange() const { return m_shroudClearingRange; } ///< get vision range for Shroud ONLY (Design requested split)
  368. //This one is okay to check directly... because it doesn't get effected by bonuses.
  369. Real getShroudRevealToAllRange() const { return m_shroudRevealToAllRange; }
  370. // This function is only for use by the AIUpdateModuleData::parseLocomotorSet function.
  371. AIUpdateModuleData *friend_getAIModuleInfo(void);
  372. ShadowType getShadowType() const { return (ShadowType)m_shadowType; }
  373. Real getShadowSizeX() const { return m_shadowSizeX; }
  374. Real getShadowSizeY() const { return m_shadowSizeY; }
  375. Real getShadowOffsetX() const { return m_shadowOffsetX; }
  376. Real getShadowOffsetY() const { return m_shadowOffsetY; }
  377. const AsciiString& getShadowTextureName( void ) const { return m_shadowTextureName; }
  378. UnsignedInt getOcclusionDelay(void) const { return m_occlusionDelay;}
  379. const ModuleInfo& getBehaviorModuleInfo() const { return m_behaviorModuleInfo; }
  380. const ModuleInfo& getDrawModuleInfo() const { return m_drawModuleInfo; }
  381. const ModuleInfo& getClientUpdateModuleInfo() const { return m_clientUpdateModuleInfo; }
  382. const Image *getSelectedPortraitImage( void ) const { return m_selectedPortraitImage; }
  383. const Image *getButtonImage( void ) const { return m_buttonImage; }
  384. //Code renderer handles these states now.
  385. //const AsciiString& getInventoryImageName( InventoryImageType type ) const { return m_inventoryImage[ type ]; }
  386. Int getSkillPointValue(Int level) const;
  387. Int getExperienceValue(Int level) const { return m_experienceValues[level]; }
  388. Int getExperienceRequired(Int level) const {return m_experienceRequired[level]; }
  389. Bool isTrainable() const{return m_isTrainable; }
  390. Bool isEnterGuard() const{return m_enterGuard; }
  391. Bool isHijackGuard() const{return m_hijackGuard; }
  392. const AudioEventRTS *getVoiceSelect() const { return getAudio(TTAUDIO_voiceSelect); }
  393. const AudioEventRTS *getVoiceGroupSelect() const { return getAudio(TTAUDIO_voiceGroupSelect); }
  394. const AudioEventRTS *getVoiceMove() const { return getAudio(TTAUDIO_voiceMove); }
  395. const AudioEventRTS *getVoiceAttack() const { return getAudio(TTAUDIO_voiceAttack); }
  396. const AudioEventRTS *getVoiceEnter() const { return getAudio(TTAUDIO_voiceEnter); }
  397. const AudioEventRTS *getVoiceFear() const { return getAudio(TTAUDIO_voiceFear); }
  398. const AudioEventRTS *getVoiceSelectElite() const { return getAudio(TTAUDIO_voiceSelectElite); }
  399. const AudioEventRTS *getVoiceCreated() const { return getAudio(TTAUDIO_voiceCreated); }
  400. const AudioEventRTS *getVoiceNearEnemy() const { return getAudio(TTAUDIO_voiceNearEnemy); }
  401. const AudioEventRTS *getVoiceTaskUnable() const { return getAudio(TTAUDIO_voiceTaskUnable); }
  402. const AudioEventRTS *getVoiceTaskComplete() const { return getAudio(TTAUDIO_voiceTaskComplete); }
  403. const AudioEventRTS *getVoiceMeetEnemy() const { return getAudio(TTAUDIO_voiceMeetEnemy); }
  404. const AudioEventRTS *getVoiceGarrison() const { return getAudio(TTAUDIO_voiceGarrison); }
  405. #ifdef ALLOW_SURRENDER
  406. const AudioEventRTS *getVoiceSurrender() const { return getAudio(TTAUDIO_voiceSurrender); }
  407. #endif
  408. const AudioEventRTS *getVoiceDefect() const { return getAudio(TTAUDIO_voiceDefect); }
  409. const AudioEventRTS *getVoiceAttackSpecial() const { return getAudio(TTAUDIO_voiceAttackSpecial); }
  410. const AudioEventRTS *getVoiceAttackAir() const { return getAudio(TTAUDIO_voiceAttackAir); }
  411. const AudioEventRTS *getVoiceGuard() const { return getAudio(TTAUDIO_voiceGuard); }
  412. const AudioEventRTS *getSoundMoveStart() const { return getAudio(TTAUDIO_soundMoveStart); }
  413. const AudioEventRTS *getSoundMoveStartDamaged() const { return getAudio(TTAUDIO_soundMoveStartDamaged); }
  414. const AudioEventRTS *getSoundMoveLoop() const { return getAudio(TTAUDIO_soundMoveLoop); }
  415. const AudioEventRTS *getSoundMoveLoopDamaged() const { return getAudio(TTAUDIO_soundMoveLoopDamaged); }
  416. const AudioEventRTS *getSoundAmbient() const { return getAudio(TTAUDIO_soundAmbient); }
  417. const AudioEventRTS *getSoundAmbientDamaged() const { return getAudio(TTAUDIO_soundAmbientDamaged); }
  418. const AudioEventRTS *getSoundAmbientReallyDamaged() const { return getAudio(TTAUDIO_soundAmbientReallyDamaged); }
  419. const AudioEventRTS *getSoundAmbientRubble() const { return getAudio(TTAUDIO_soundAmbientRubble); }
  420. const AudioEventRTS *getSoundStealthOn() const { return getAudio(TTAUDIO_soundStealthOn); }
  421. const AudioEventRTS *getSoundStealthOff() const { return getAudio(TTAUDIO_soundStealthOff); }
  422. const AudioEventRTS *getSoundCreated() const { return getAudio(TTAUDIO_soundCreated); }
  423. const AudioEventRTS *getSoundOnDamaged() const { return getAudio(TTAUDIO_soundOnDamaged); }
  424. const AudioEventRTS *getSoundOnReallyDamaged() const { return getAudio(TTAUDIO_soundOnReallyDamaged); }
  425. const AudioEventRTS *getSoundEnter() const { return getAudio(TTAUDIO_soundEnter); }
  426. const AudioEventRTS *getSoundExit() const { return getAudio(TTAUDIO_soundExit); }
  427. const AudioEventRTS *getSoundPromotedVeteran() const { return getAudio(TTAUDIO_soundPromotedVeteran); }
  428. const AudioEventRTS *getSoundPromotedElite() const { return getAudio(TTAUDIO_soundPromotedElite); }
  429. const AudioEventRTS *getSoundPromotedHero() const { return getAudio(TTAUDIO_soundPromotedHero); }
  430. const AudioEventRTS *getSoundFalling() const { return getAudio(TTAUDIO_soundFalling); }
  431. Bool hasSoundAmbient() const { return hasAudio(TTAUDIO_soundAmbient); }
  432. const AudioEventRTS *getPerUnitSound(const AsciiString& soundName) const;
  433. const FXList* getPerUnitFX(const AsciiString& fxName) const;
  434. UnsignedInt getThreatValue() const { return m_threatValue; }
  435. //-------------------------------------------------------------------------------------------------
  436. /** If this is not NAMEKEY_INVALID, it indicates that all the templates which return the same name key
  437. * should be counted as the same "type" when looking at getMaxSimultaneousOfType(). For instance,
  438. * a Scud Storm and a Scud Storm rebuild hole will return the same value, so that the player
  439. * can't build another Scud Storm while waiting for the rebuild hole to start rebuilding */
  440. //-------------------------------------------------------------------------------------------------
  441. NameKeyType getMaxSimultaneousLinkKey() const { return m_maxSimultaneousLinkKey; }
  442. UnsignedInt getMaxSimultaneousOfType() const;
  443. void validate();
  444. // The version that does not take an Object argument is labeled friend for use by WorldBuilder. All game requests
  445. // for CommandSet must use Object::getCommandSetString, as we have two different sources for dynamic answers.
  446. const AsciiString& friend_getCommandSetString() const { return m_commandSetString; }
  447. const std::vector<AsciiString>& getBuildVariations() const { return m_buildVariations; }
  448. Real getAssetScale() const { return m_assetScale; } ///< return uniform scaling
  449. Real getInstanceScaleFuzziness() const { return m_instanceScaleFuzziness; } ///< return uniform scaling
  450. Real getStructureRubbleHeight() const { return (Real)m_structureRubbleHeight; } ///< return uniform scaling
  451. /*
  452. NOTE: if you have a Thing, don't call this function; call Thing::getGeometryInfo instead, since
  453. geometry can now vary on a per-object basis. Only call this when you have no Thing around,
  454. and want to get info for the "prototype" (eg, for building new Things)...
  455. */
  456. const GeometryInfo& getTemplateGeometryInfo() const { return m_geometryInfo; }
  457. //
  458. // these are intended ONLY for the private use of ThingFactory and do not use
  459. // the m_override pointer, it deals only with templates at the "top" level
  460. //
  461. inline void friend_setTemplateName( const AsciiString& name ) { m_nameString = name; }
  462. inline ThingTemplate *friend_getNextTemplate() const { return m_nextThingTemplate; }
  463. inline void friend_setNextTemplate(ThingTemplate *tmplate) { m_nextThingTemplate = tmplate; }
  464. inline void friend_setTemplateID(UnsignedShort id) { m_templateID = id; }
  465. Int getEnergyProduction() const { return m_energyProduction; }
  466. Int getEnergyBonus() const { return m_energyBonus; }
  467. // these are NOT publicly available; you should call calcCostToBuild() or calcTimeToBuild()
  468. // instead, because they will take player handicaps into account.
  469. // Int getBuildCost() const { return m_buildCost; }
  470. Int getRefundValue() const { return m_refundValue; }
  471. BuildCompletionType getBuildCompletion() const { return (BuildCompletionType)m_buildCompletion; }
  472. BuildableStatus getBuildable() const;
  473. Int getPrereqCount() const { return m_prereqInfo.size(); }
  474. const ProductionPrerequisite *getNthPrereq(Int i) const { return &m_prereqInfo[i]; }
  475. /**
  476. return the BuildFacilityTemplate, if any.
  477. if this template needs no build facility, null is returned.
  478. if the template needs a build facility but the given player doesn't have any in existence,
  479. null will be returned.
  480. if you pass null for player, we'll return the 'natural' build facility.
  481. */
  482. const ThingTemplate *getBuildFacilityTemplate( const Player *player ) const;
  483. Bool isBuildableItem(void) const;
  484. /// calculate how long (in logic frames) it will take the given player to build this unit
  485. Int calcTimeToBuild( const Player* player) const;
  486. /// calculate how much money it will take the given player to build this unit
  487. Int calcCostToBuild( const Player* player) const;
  488. /// Used only by Skirmish AI. Everyone else should call calcCostToBuild.
  489. Int friend_getBuildCost() const { return m_buildCost; }
  490. const AsciiString& getDefaultOwningSide() const { return m_defaultOwningSide; }
  491. /// get us the table to parse the fields for thing templates
  492. const FieldParse* getFieldParse() const { return s_objectFieldParseTable; }
  493. const FieldParse* getReskinFieldParse() const { return s_objectReskinFieldParseTable; }
  494. Bool isBuildFacility() const { return m_isBuildFacility; }
  495. Real getPlacementViewAngle( void ) const { return m_placementViewAngle; }
  496. Real getFactoryExitWidth() const { return m_factoryExitWidth; }
  497. Real getFactoryExtraBibWidth() const { return m_factoryExtraBibWidth; }
  498. void setCopiedFromDefault();
  499. void setReskinnedFrom(const ThingTemplate* tt) { DEBUG_ASSERTCRASH(m_reskinnedFrom == NULL, ("should be null")); m_reskinnedFrom = tt; }
  500. Bool isPrerequisite() const { return m_isPrerequisite; }
  501. const WeaponTemplateSet* findWeaponTemplateSet(const WeaponSetFlags& t) const;
  502. const ArmorTemplateSet* findArmorTemplateSet(const ArmorSetFlags& t) const;
  503. // returns true iff we have at least one weaponset that contains a weapon.
  504. // returns false if we have no weaponsets, or they are all empty.
  505. Bool canPossiblyHaveAnyWeapon() const;
  506. Bool isEquivalentTo(const ThingTemplate* tt) const;
  507. UnsignedByte getCrushableLevel() const { return m_crushableLevel; }
  508. UnsignedByte getCrusherLevel() const { return m_crusherLevel; }
  509. AsciiString getUpgradeCameoName( Int n)const{ return m_upgradeCameoUpgradeNames[n]; }
  510. const WeaponTemplateSetVector& getWeaponTemplateSets(void) const {return m_weaponTemplateSets;}
  511. protected:
  512. //
  513. // these are NOT publicly available; you should call calcCostToBuild() or calcTimeToBuild()
  514. // instead, because they will take player handicaps into account.
  515. //
  516. Int getBuildCost() const { return m_buildCost; }
  517. Real getBuildTime() const { return m_buildTime; }
  518. const PerUnitSoundMap* getAllPerUnitSounds( void ) const { return &m_perUnitSounds; }
  519. void validateAudio();
  520. const AudioEventRTS* getAudio(ThingTemplateAudioType t) const { return m_audioarray.m_audio[t] ? &m_audioarray.m_audio[t]->m_event : &s_audioEventNoSound; }
  521. Bool hasAudio(ThingTemplateAudioType t) const { return m_audioarray.m_audio[t] != NULL; }
  522. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  523. /** Table for parsing the object fields */
  524. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  525. static void parseArmorTemplateSet( INI* ini, void *instance, void *store, const void* /*userData*/ );
  526. static void parseWeaponTemplateSet( INI* ini, void *instance, void *store, const void* /*userData*/ );
  527. static void parsePrerequisites( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ );
  528. static void parseModuleName(INI* ini, void *instance, void* /*store*/, const void* userData);
  529. static void parseIntList(INI* ini, void *instance, void* store, const void* userData);
  530. static void parsePerUnitSounds(INI* ini, void *instance, void* store, const void* userData);
  531. static void parsePerUnitFX(INI* ini, void *instance, void* store, const void* userData);
  532. static void parseAddModule(INI *ini, void *instance, void *store, const void *userData);
  533. static void parseRemoveModule(INI *ini, void *instance, void *store, const void *userData);
  534. static void parseReplaceModule(INI *ini, void *instance, void *store, const void *userData);
  535. static void parseInheritableModule(INI *ini, void *instance, void *store, const void *userData);
  536. static void OverrideableByLikeKind(INI *ini, void *instance, void *store, const void *userData);
  537. static void parseMaxSimultaneous(INI *ini, void *instance, void *store, const void *userData);
  538. Bool removeModuleInfo(const AsciiString& moduleToRemove, AsciiString& clearedModuleNameOut);
  539. private:
  540. static const FieldParse s_objectFieldParseTable[]; ///< the parse table
  541. static const FieldParse s_objectReskinFieldParseTable[]; ///< the parse table
  542. static AudioEventRTS s_audioEventNoSound;
  543. private:
  544. // ---- Strings
  545. UnicodeString m_displayName; ///< UI display for onscreen display
  546. AsciiString m_nameString; ///< name of this thing template
  547. AsciiString m_defaultOwningSide; ///< default owning side (owning player is inferred)
  548. AsciiString m_commandSetString;
  549. AsciiString m_selectedPortraitImageName;
  550. AsciiString m_buttonImageName;
  551. AsciiString m_upgradeCameoUpgradeNames[MAX_UPGRADE_CAMEO_UPGRADES]; ///< Use these to find the upgrade images to display on the control bar
  552. AsciiString m_shadowTextureName; ///< name of texture to use for shadow decal
  553. AsciiString m_moduleBeingReplacedName; ///< used only during map.ini loading... name (not tag) of Module being replaced, or empty if not inside ReplaceModule block
  554. AsciiString m_moduleBeingReplacedTag; ///< used only during map.ini loading... tag (not name) of Module being replaced, or empty if not inside ReplaceModule block
  555. #ifdef LOAD_TEST_ASSETS
  556. AsciiString m_LTAName;
  557. #endif
  558. // ---- Misc Larger-than-int things
  559. GeometryInfo m_geometryInfo; ///< geometry information
  560. KindOfMaskType m_kindof; ///< kindof bits
  561. AudioArray m_audioarray;
  562. ModuleInfo m_behaviorModuleInfo;
  563. ModuleInfo m_drawModuleInfo;
  564. ModuleInfo m_clientUpdateModuleInfo;
  565. // ---- Misc Arrays-of-things
  566. Int m_skillPointValues[LEVEL_COUNT];
  567. Int m_experienceValues[LEVEL_COUNT]; ///< How much I am worth at each experience level
  568. Int m_experienceRequired[LEVEL_COUNT]; ///< How many experience points I need for each level
  569. //Code renderer handles these states now.
  570. //AsciiString m_inventoryImage[ INV_IMAGE_NUM_IMAGES ]; ///< portrait inventory pictures
  571. // ---- STL-sized things
  572. std::vector<ProductionPrerequisite> m_prereqInfo; ///< the unit Prereqs for this tech
  573. std::vector<AsciiString> m_buildVariations; /**< if we build a unit of this type via script or ui, randomly choose one
  574. of these templates instead. (doesn't apply to MapObject-created items) */
  575. WeaponTemplateSetVector m_weaponTemplateSets; ///< our weaponsets
  576. WeaponTemplateSetFinder m_weaponTemplateSetFinder; ///< helper to allow us to find the best sets, quickly
  577. ArmorTemplateSetVector m_armorTemplateSets; ///< our armorsets
  578. ArmorTemplateSetFinder m_armorTemplateSetFinder; ///< helper to allow us to find the best sets, quickly
  579. PerUnitSoundMap m_perUnitSounds; ///< An additional set of sounds that only apply for this template.
  580. PerUnitFXMap m_perUnitFX; ///< An additional set of fx that only apply for this template.
  581. // ---- Pointer-sized things
  582. ThingTemplate* m_nextThingTemplate;
  583. const ThingTemplate* m_reskinnedFrom; ///< non NULL if we were generated via a reskin
  584. const Image * m_selectedPortraitImage; /// portrait image when selected (to display in GUI)
  585. const Image * m_buttonImage;
  586. // ---- Real-sized things
  587. Real m_fenceWidth; ///< Fence width for fence type objects.
  588. Real m_fenceXOffset; ///< Fence X offset for fence type objects.
  589. Real m_visionRange; ///< object "sees" this far around itself
  590. Real m_shroudClearingRange; ///< Since So many things got added to "Seeing" functionality, we need to split this part out.
  591. Real m_shroudRevealToAllRange; ///< When > zero, the shroud gets revealed to all players.
  592. Real m_placementViewAngle; ///< when placing buildings this will be the angle of the building when "floating" at the mouse
  593. Real m_factoryExitWidth; ///< when placing buildings this will be the width of the reserved exit area on the right side.
  594. Real m_factoryExtraBibWidth; ///< when placing buildings this will be the width of the reserved exit area on the right side.
  595. Real m_buildTime; ///< Seconds to build
  596. Real m_assetScale;
  597. Real m_instanceScaleFuzziness; ///< scale randomization tolerance to init for each Drawable instance,
  598. Real m_shadowSizeX; ///< world-space extent of decal shadow texture
  599. Real m_shadowSizeY; ///< world-space extent of decal shadow texture
  600. Real m_shadowOffsetX; ///< world-space offset of decal shadow texture
  601. Real m_shadowOffsetY; ///< world-space offset of decal shadow texture
  602. // ---- Int-sized things
  603. Int m_energyProduction; ///< how much Energy this takes (negative values produce Energy, rather than consuming it)
  604. Int m_energyBonus; ///< how much extra Energy this produces due to the upgrade
  605. Color m_displayColor; ///< for the editor display color
  606. UnsignedInt m_occlusionDelay; ///< delay after object creation before building occlusion is allowed.
  607. NameKeyType m_maxSimultaneousLinkKey; ///< If this is not NAMEKEY_INVALID, it indicates that all the templates which have the same name key should be counted as the same "type" when looking at getMaxSimultaneousOfType().
  608. // ---- Short-sized things
  609. UnsignedShort m_templateID; ///< id for net (etc.) transmission purposes
  610. UnsignedShort m_buildCost; ///< money to build (0 == not buildable)
  611. UnsignedShort m_refundValue; ///< custom resale value, if sold. (0 == use default)
  612. UnsignedShort m_threatValue; ///< Threat map info
  613. UnsignedShort m_maxSimultaneousOfType; ///< max simultaneous of this unit we can have (per player) at one time. (0 == unlimited)
  614. // ---- Bool-sized things
  615. Bool m_maxSimultaneousDeterminedBySuperweaponRestriction; ///< If true, override value in m_maxSimultaneousOfType with value from GameInfo::getSuperweaponRestriction()
  616. Bool m_isPrerequisite; ///< Is this thing considered in a prerequisite for any other thing?
  617. Bool m_isBridge; ///< True if this model is a bridge.
  618. Bool m_isBuildFacility; ///< is this the build facility for something? (calculated based on other template's prereqs)
  619. Bool m_isTrainable; ///< Whether or not I can even gain experience
  620. Bool m_enterGuard; ///< Whether or not I can enter objects when guarding
  621. Bool m_hijackGuard; ///< Whether or not I can hijack objects when guarding
  622. Bool m_isForbidden; ///< useful when overriding in <mapfile>.ini
  623. Bool m_armorCopiedFromDefault;
  624. Bool m_weaponsCopiedFromDefault;
  625. // ---- Byte-sized things
  626. Byte m_radarPriority; ///< does object appear on radar, and if so at what priority
  627. Byte m_transportSlotCount; ///< how many "slots" we take in a transport (0 == not transportable)
  628. Byte m_buildable; ///< is this thing buildable at all?
  629. Byte m_buildCompletion; ///< how the units come into the world when build is complete
  630. Byte m_editorSorting; ///< editor sorting type, see EditorSortingType enum
  631. Byte m_structureRubbleHeight;
  632. Byte m_shadowType; ///< settings which determine the type of shadow rendered
  633. Byte m_moduleParsingMode;
  634. UnsignedByte m_crusherLevel; ///< crusher > crushable level to actually crush
  635. UnsignedByte m_crushableLevel; ///< Specifies the level of crushability (must be hit by a crusher greater than this to crush me).
  636. };
  637. //-----------------------------------------------------------------------------
  638. // Inlining
  639. //-----------------------------------------------------------------------------
  640. //-----------------------------------------------------------------------------
  641. // Externals
  642. //-----------------------------------------------------------------------------
  643. #endif // __THINGTEMPLATE_H_