ThingTemplate.h 33 KB

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