EntityProperties.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. #include "stdh.h"
  13. #include <Engine/Entities/EntityProperties.h>
  14. #include <Engine/Entities/Precaching.h>
  15. #include <Engine/Base/Stream.h>
  16. #include <Engine/Base/CRCTable.h>
  17. #include <Engine/Base/Console.h>
  18. #include <Engine/World/World.h>
  19. #include <Engine/Base/ReplaceFile.h>
  20. #include <Engine/Sound/SoundObject.h>
  21. #include <Engine/Math/Quaternion.h>
  22. #include <Engine/Templates/Stock_CAnimData.h>
  23. #include <Engine/Templates/Stock_CTextureData.h>
  24. #include <Engine/Templates/Stock_CModelData.h>
  25. #include <Engine/Templates/Stock_CSoundData.h>
  26. #include <Engine/Templates/Stock_CEntityClass.h>
  27. #include <Engine/Templates/StaticArray.cpp>
  28. #define FILTER_ALL "All files (*.*)\0*.*\0"
  29. #define FILTER_END "\0"
  30. #define PROPERTY(offset, type) ENTITYPROPERTY(this, offset, type)
  31. /////////////////////////////////////////////////////////////////////
  32. // Property management functions
  33. /*
  34. * Set all properties to default values.
  35. */
  36. void CEntity::SetDefaultProperties(void)
  37. {
  38. // no properties to set in base class
  39. }
  40. /*
  41. * Helpers for writing/reading entity pointers.
  42. */
  43. void CEntity::ReadEntityPointer_t(CTStream *istrm, CEntityPointer &pen)
  44. {
  45. CEntity *penPointed;
  46. // read index
  47. INDEX iPointedEntity;
  48. *istrm>>iPointedEntity;
  49. // if there is no entity pointed to
  50. if (iPointedEntity == -1) {
  51. // set NULL pointer
  52. penPointed = NULL;
  53. // if there is some entity
  54. } else {
  55. // get the entity in this world with that index
  56. extern BOOL _bReadEntitiesByID;
  57. if (_bReadEntitiesByID) {
  58. penPointed = en_pwoWorld->EntityFromID(iPointedEntity);
  59. } else {
  60. penPointed = en_pwoWorld->wo_cenAllEntities.Pointer(iPointedEntity);
  61. }
  62. }
  63. // return the entity pointer
  64. pen = penPointed;
  65. }
  66. void CEntity::WriteEntityPointer_t(CTStream *ostrm, CEntityPointer pen)
  67. {
  68. // if there is no entity pointed to
  69. if (pen==NULL) {
  70. // write -1 index
  71. *ostrm<<(INDEX)-1;
  72. // if there is some entity
  73. } else {
  74. // the entity must be in the same world as this one
  75. ASSERT(pen->en_pwoWorld == en_pwoWorld);
  76. // write index of the entity in this world
  77. *ostrm<<(pen->en_ulID);
  78. }
  79. }
  80. /*
  81. * Read all properties from a stream.
  82. */
  83. void CEntity::ReadProperties_t(CTStream &istrm) // throw char *
  84. {
  85. istrm.ExpectID_t("PRPS"); // 'properties'
  86. CDLLEntityClass *pdecDLLClass = en_pecClass->ec_pdecDLLClass;
  87. INDEX ctProperties;
  88. // read number of properties (note that this doesn't have to be same as number
  89. // of properties in the class (class might have changed))
  90. istrm>>ctProperties;
  91. // for all saved properties
  92. for(INDEX iProperty=0; iProperty<ctProperties; iProperty++) {
  93. pdecDLLClass->dec_ctProperties;
  94. // read packed identifier
  95. ULONG ulIDAndType;
  96. istrm>>ulIDAndType;
  97. // unpack property ID and property type from the identifier
  98. ULONG ulID;
  99. CEntityProperty::PropertyType eptType;
  100. ulID = ulIDAndType>>8;
  101. eptType = (CEntityProperty::PropertyType )(ulIDAndType&0x000000FFUL);
  102. // get the property with that ID and type
  103. CEntityProperty *pepProperty = PropertyForTypeAndID(eptType, ulID);
  104. // if not found, but it is a string
  105. if (pepProperty == NULL && eptType==CEntityProperty::EPT_STRING) {
  106. // maybe that became translatable string try that
  107. pepProperty = PropertyForTypeAndID(CEntityProperty::EPT_STRINGTRANS, ulID);
  108. // NOTE: it is still loaded as string, without translation chunk,
  109. // we just find it in properties table as a translatable string.
  110. }
  111. // if it was not found
  112. if (pepProperty == NULL) {
  113. // depending on the property type
  114. switch (eptType) {
  115. // if it is BOOL
  116. case CEntityProperty::EPT_BOOL: {
  117. // skip BOOL
  118. BOOL bDummy;
  119. istrm>>(INDEX &)bDummy;
  120. break;
  121. }
  122. // if it is INDEX
  123. case CEntityProperty::EPT_INDEX:
  124. case CEntityProperty::EPT_ENUM:
  125. case CEntityProperty::EPT_FLAGS:
  126. case CEntityProperty::EPT_ANIMATION:
  127. case CEntityProperty::EPT_ILLUMINATIONTYPE:
  128. case CEntityProperty::EPT_COLOR:
  129. case CEntityProperty::EPT_ANGLE: {
  130. // skip INDEX
  131. INDEX iDummy;
  132. istrm>>iDummy;
  133. } break;
  134. // if it is FLOAT
  135. case CEntityProperty::EPT_FLOAT:
  136. case CEntityProperty::EPT_RANGE: {
  137. // skip FLOAT
  138. FLOAT fDummy;
  139. istrm>>fDummy;
  140. }
  141. break;
  142. // if it is STRING
  143. case CEntityProperty::EPT_STRING: {
  144. // skip STRING
  145. CTString strDummy;
  146. istrm>>strDummy;
  147. break;
  148. }
  149. // if it is STRINGTRANS
  150. case CEntityProperty::EPT_STRINGTRANS: {
  151. // skip STRINGTRANS
  152. istrm.ExpectID_t("DTRS");
  153. CTString strDummy;
  154. istrm>>strDummy;
  155. break;
  156. }
  157. // if it is FILENAME
  158. case CEntityProperty::EPT_FILENAME: {
  159. // skip FILENAME
  160. CTFileName fnmDummy;
  161. istrm>>fnmDummy;
  162. break;
  163. }
  164. // if it is FILENAMENODEP
  165. case CEntityProperty::EPT_FILENAMENODEP: {
  166. // skip FILENAMENODEP
  167. CTFileNameNoDep fnmDummy;
  168. istrm>>fnmDummy;
  169. break;
  170. }
  171. // if it is ENTITYPTR
  172. case CEntityProperty::EPT_ENTITYPTR: {
  173. // skip index
  174. INDEX iDummy;
  175. istrm>>iDummy;
  176. }
  177. break;
  178. // if it is FLOATAABBOX3D
  179. case CEntityProperty::EPT_FLOATAABBOX3D: {
  180. // skip FLOATAABBOX3D
  181. FLOATaabbox3D boxDummy;
  182. istrm.Read_t(&boxDummy, sizeof(FLOATaabbox3D));
  183. }
  184. break;
  185. // if it is FLOATMATRIX3D
  186. case CEntityProperty::EPT_FLOATMATRIX3D: {
  187. // skip FLOATMATRIX3D
  188. FLOATmatrix3D boxDummy;
  189. istrm.Read_t(&boxDummy, sizeof(FLOATmatrix3D));
  190. }
  191. break;
  192. // if it is EPT_FLOATQUAT3D
  193. case CEntityProperty::EPT_FLOATQUAT3D: {
  194. // skip EPT_FLOATQUAT3D
  195. FLOATquat3D qDummy;
  196. istrm.Read_t(&qDummy, sizeof(FLOATquat3D));
  197. }
  198. break;
  199. // if it is FLOAT3D
  200. case CEntityProperty::EPT_FLOAT3D: {
  201. // skip FLOAT3D
  202. FLOAT3D vDummy;
  203. istrm>>vDummy;
  204. }
  205. break;
  206. // if it is ANGLE3D
  207. case CEntityProperty::EPT_ANGLE3D: {
  208. // skip ANGLE3D
  209. ANGLE3D vDummy;
  210. istrm>>vDummy;
  211. }
  212. break;
  213. // if it is FLOATplane3D
  214. case CEntityProperty::EPT_FLOATplane3D: {
  215. // skip FLOATplane3D
  216. FLOATplane3D plDummy;
  217. istrm.Read_t(&plDummy, sizeof(plDummy));
  218. }
  219. break;
  220. // if it is MODELOBJECT
  221. case CEntityProperty::EPT_MODELOBJECT:
  222. // skip CModelObject
  223. SkipModelObject_t(istrm);
  224. break;
  225. // if it is MODELINSTANCE
  226. case CEntityProperty::EPT_MODELINSTANCE:
  227. SkipModelInstance_t(istrm);
  228. break;
  229. // if it is ANIMOBJECT
  230. case CEntityProperty::EPT_ANIMOBJECT:
  231. // skip CAnimObject
  232. SkipAnimObject_t(istrm);
  233. break;
  234. // if it is SOUNDOBJECT
  235. case CEntityProperty::EPT_SOUNDOBJECT:
  236. // skip CSoundObject
  237. SkipSoundObject_t(istrm);
  238. break;
  239. default:
  240. ASSERTALWAYS("Unknown property type");
  241. }
  242. // if it was found
  243. } else {
  244. // fixup for loading old strings as translatable strings
  245. CEntityProperty::PropertyType eptLoad = pepProperty->ep_eptType;
  246. if (eptType==CEntityProperty::EPT_STRING &&
  247. eptLoad==CEntityProperty::EPT_STRINGTRANS) {
  248. eptLoad = CEntityProperty::EPT_STRING;
  249. }
  250. // depending on the property type
  251. switch (eptLoad) {
  252. // if it is BOOL
  253. case CEntityProperty::EPT_BOOL:
  254. // read BOOL
  255. istrm>>(INDEX &)PROPERTY(pepProperty->ep_slOffset, BOOL);
  256. break;
  257. // if it is INDEX
  258. case CEntityProperty::EPT_INDEX:
  259. case CEntityProperty::EPT_ENUM:
  260. case CEntityProperty::EPT_FLAGS:
  261. case CEntityProperty::EPT_ANIMATION:
  262. case CEntityProperty::EPT_ILLUMINATIONTYPE:
  263. case CEntityProperty::EPT_COLOR:
  264. case CEntityProperty::EPT_ANGLE:
  265. // read INDEX
  266. istrm>>PROPERTY(pepProperty->ep_slOffset, INDEX);
  267. break;
  268. // if it is FLOAT
  269. case CEntityProperty::EPT_FLOAT:
  270. case CEntityProperty::EPT_RANGE:
  271. // read FLOAT
  272. istrm>>PROPERTY(pepProperty->ep_slOffset, FLOAT);
  273. break;
  274. // if it is STRING
  275. case CEntityProperty::EPT_STRING:
  276. // read STRING
  277. istrm>>PROPERTY(pepProperty->ep_slOffset, CTString);
  278. break;
  279. // if it is STRINGTRANS
  280. case CEntityProperty::EPT_STRINGTRANS:
  281. // read STRINGTRANS
  282. istrm.ExpectID_t("DTRS");
  283. istrm>>PROPERTY(pepProperty->ep_slOffset, CTString);
  284. break;
  285. // if it is FILENAME
  286. case CEntityProperty::EPT_FILENAME:
  287. // read FILENAME
  288. istrm>>PROPERTY(pepProperty->ep_slOffset, CTFileName);
  289. if (PROPERTY(pepProperty->ep_slOffset, CTFileName)=="") {
  290. break;
  291. }
  292. // try to replace file name if it doesn't exist
  293. for(;;)
  294. {
  295. if( !FileExists( PROPERTY(pepProperty->ep_slOffset, CTFileName)))
  296. {
  297. // if file was not found, ask for replacing file
  298. CTFileName fnReplacingFile;
  299. if( GetReplacingFile( PROPERTY(pepProperty->ep_slOffset, CTFileName),
  300. fnReplacingFile, FILTER_ALL FILTER_END))
  301. {
  302. // replacing file was provided
  303. PROPERTY(pepProperty->ep_slOffset, CTFileName) = fnReplacingFile;
  304. } else {
  305. ThrowF_t(TRANS("File '%s' does not exist"), (const char*)PROPERTY(pepProperty->ep_slOffset, CTFileName));
  306. }
  307. }
  308. else
  309. {
  310. break;
  311. }
  312. }
  313. break;
  314. // if it is FILENAMENODEP
  315. case CEntityProperty::EPT_FILENAMENODEP:
  316. // read FILENAMENODEP
  317. istrm>>PROPERTY(pepProperty->ep_slOffset, CTFileNameNoDep);
  318. break;
  319. // if it is ENTITYPTR
  320. case CEntityProperty::EPT_ENTITYPTR:
  321. // read the entity pointer
  322. ReadEntityPointer_t(&istrm, PROPERTY(pepProperty->ep_slOffset, CEntityPointer));
  323. break;
  324. // if it is FLOATAABBOX3D
  325. case CEntityProperty::EPT_FLOATAABBOX3D:
  326. // read FLOATAABBOX3D
  327. istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATaabbox3D), sizeof(FLOATaabbox3D));
  328. break;
  329. // if it is FLOATMATRIX3D
  330. case CEntityProperty::EPT_FLOATMATRIX3D:
  331. // read FLOATMATRIX3D
  332. istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATmatrix3D), sizeof(FLOATmatrix3D));
  333. break;
  334. // if it is FLOATQUAT3D
  335. case CEntityProperty::EPT_FLOATQUAT3D:
  336. // read FLOATQUAT3D
  337. istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATquat3D), sizeof(FLOATquat3D));
  338. break;
  339. // if it is FLOAT3D
  340. case CEntityProperty::EPT_FLOAT3D:
  341. // read FLOAT3D
  342. istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOAT3D), sizeof(FLOAT3D));
  343. break;
  344. // if it is ANGLE3D
  345. case CEntityProperty::EPT_ANGLE3D:
  346. // read ANGLE3D
  347. istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, ANGLE3D), sizeof(ANGLE3D));
  348. break;
  349. // if it is FLOATplane3D
  350. case CEntityProperty::EPT_FLOATplane3D:
  351. // read FLOATplane3D
  352. istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, FLOATplane3D), sizeof(FLOATplane3D));
  353. break;
  354. // if it is MODELOBJECT
  355. case CEntityProperty::EPT_MODELOBJECT:
  356. // read CModelObject
  357. ReadModelObject_t(istrm, PROPERTY(pepProperty->ep_slOffset, CModelObject));
  358. break;
  359. // if it is MODELINSTANCE
  360. case CEntityProperty::EPT_MODELINSTANCE:
  361. // read CModelObject
  362. ReadModelInstance_t(istrm, PROPERTY(pepProperty->ep_slOffset, CModelInstance));
  363. break;
  364. // if it is ANIMOBJECT
  365. case CEntityProperty::EPT_ANIMOBJECT:
  366. // read CAnimObject
  367. ReadAnimObject_t(istrm, PROPERTY(pepProperty->ep_slOffset, CAnimObject));
  368. break;
  369. // if it is SOUNDOBJECT
  370. case CEntityProperty::EPT_SOUNDOBJECT:
  371. // read CSoundObject
  372. {
  373. CSoundObject &so = PROPERTY(pepProperty->ep_slOffset, CSoundObject);
  374. ReadSoundObject_t(istrm, so);
  375. so.so_penEntity = this;
  376. }
  377. break;
  378. // if it is CPlacement3D
  379. case CEntityProperty::EPT_PLACEMENT3D:
  380. // read CPlacement3D
  381. istrm.Read_t(&PROPERTY(pepProperty->ep_slOffset, CPlacement3D), sizeof(CPlacement3D));
  382. break;
  383. default:
  384. ASSERTALWAYS("Unknown property type");
  385. }
  386. }
  387. }
  388. }
  389. /*
  390. * Write all properties to a stream.
  391. */
  392. void CEntity::WriteProperties_t(CTStream &ostrm) // throw char *
  393. {
  394. INDEX ctProperties = 0;
  395. // for all classes in hierarchy of this entity
  396. {for(CDLLEntityClass *pdecDLLClass = en_pecClass->ec_pdecDLLClass;
  397. pdecDLLClass!=NULL;
  398. pdecDLLClass = pdecDLLClass->dec_pdecBase) {
  399. // count the properties
  400. ctProperties+=pdecDLLClass->dec_ctProperties;
  401. }}
  402. ostrm.WriteID_t("PRPS"); // 'properties'
  403. // write number of properties
  404. ostrm<<ctProperties;
  405. // for all classes in hierarchy of this entity
  406. {for(CDLLEntityClass *pdecDLLClass = en_pecClass->ec_pdecDLLClass;
  407. pdecDLLClass!=NULL;
  408. pdecDLLClass = pdecDLLClass->dec_pdecBase) {
  409. // for all properties
  410. for(INDEX iProperty=0; iProperty<pdecDLLClass->dec_ctProperties; iProperty++) {
  411. CEntityProperty &epProperty = pdecDLLClass->dec_aepProperties[iProperty];
  412. // pack property ID and property type together
  413. ULONG ulID = epProperty.ep_ulID;
  414. ULONG ulType = (ULONG)epProperty.ep_eptType;
  415. ULONG ulIDAndType = (ulID<<8)|ulType;
  416. // write the packed identifier
  417. ostrm<<ulIDAndType;
  418. // depending on the property type
  419. switch (epProperty.ep_eptType) {
  420. // if it is BOOL
  421. case CEntityProperty::EPT_BOOL:
  422. // write BOOL
  423. ostrm<<(INDEX &)PROPERTY(epProperty.ep_slOffset, BOOL);
  424. break;
  425. // if it is INDEX
  426. case CEntityProperty::EPT_INDEX:
  427. case CEntityProperty::EPT_ENUM:
  428. case CEntityProperty::EPT_FLAGS:
  429. case CEntityProperty::EPT_ANIMATION:
  430. case CEntityProperty::EPT_ILLUMINATIONTYPE:
  431. case CEntityProperty::EPT_COLOR:
  432. case CEntityProperty::EPT_ANGLE:
  433. // write INDEX
  434. ostrm<<PROPERTY(epProperty.ep_slOffset, INDEX);
  435. break;
  436. // if it is FLOAT
  437. case CEntityProperty::EPT_FLOAT:
  438. case CEntityProperty::EPT_RANGE:
  439. // write FLOAT
  440. ostrm<<PROPERTY(epProperty.ep_slOffset, FLOAT);
  441. break;
  442. // if it is STRING
  443. case CEntityProperty::EPT_STRING:
  444. // write STRING
  445. ostrm<<PROPERTY(epProperty.ep_slOffset, CTString);
  446. break;
  447. // if it is STRINGTRANS
  448. case CEntityProperty::EPT_STRINGTRANS:
  449. // write STRINGTRANS
  450. ostrm.WriteID_t("DTRS");
  451. ostrm<<PROPERTY(epProperty.ep_slOffset, CTString);
  452. break;
  453. // if it is FILENAME
  454. case CEntityProperty::EPT_FILENAME:
  455. // write FILENAME
  456. ostrm<<PROPERTY(epProperty.ep_slOffset, CTFileName);
  457. break;
  458. // if it is FILENAMENODEP
  459. case CEntityProperty::EPT_FILENAMENODEP:
  460. // write FILENAMENODEP
  461. ostrm<<PROPERTY(epProperty.ep_slOffset, CTFileNameNoDep);
  462. break;
  463. // if it is FLOATAABBOX3D
  464. case CEntityProperty::EPT_FLOATAABBOX3D:
  465. // write FLOATAABBOX3D
  466. ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATaabbox3D), sizeof(FLOATaabbox3D));
  467. break;
  468. // if it is FLOATMATRIX3D
  469. case CEntityProperty::EPT_FLOATMATRIX3D:
  470. // write FLOATMATRIX3D
  471. ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATmatrix3D), sizeof(FLOATmatrix3D));
  472. break;
  473. // if it is FLOATQUAT3D
  474. case CEntityProperty::EPT_FLOATQUAT3D:
  475. // write FLOATQUAT3D
  476. ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATquat3D), sizeof(FLOATquat3D));
  477. break;
  478. // if it is ANGLE3D
  479. case CEntityProperty::EPT_ANGLE3D:
  480. // write ANGLE3D
  481. ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, ANGLE3D), sizeof(ANGLE3D));
  482. break;
  483. // if it is FLOAT3D
  484. case CEntityProperty::EPT_FLOAT3D:
  485. // write FLOAT3D
  486. ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOAT3D), sizeof(FLOAT3D));
  487. break;
  488. // if it is FLOATplane3D
  489. case CEntityProperty::EPT_FLOATplane3D:
  490. // write FLOATplane3D
  491. ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, FLOATplane3D), sizeof(FLOATplane3D));
  492. break;
  493. // if it is ENTITYPTR
  494. case CEntityProperty::EPT_ENTITYPTR:
  495. // write entity pointer
  496. WriteEntityPointer_t(&ostrm, PROPERTY(epProperty.ep_slOffset, CEntityPointer));
  497. break;
  498. // if it is MODELOBJECT
  499. case CEntityProperty::EPT_MODELOBJECT:
  500. // write CModelObject
  501. WriteModelObject_t(ostrm, PROPERTY(epProperty.ep_slOffset, CModelObject));
  502. break;
  503. // if it is MODELINSTANCE
  504. case CEntityProperty::EPT_MODELINSTANCE:
  505. // write CModelInstance
  506. WriteModelInstance_t(ostrm, PROPERTY(epProperty.ep_slOffset, CModelInstance));
  507. break;
  508. // if it is ANIMOBJECT
  509. case CEntityProperty::EPT_ANIMOBJECT:
  510. // write CAnimObject
  511. WriteAnimObject_t(ostrm, PROPERTY(epProperty.ep_slOffset, CAnimObject));
  512. break;
  513. // if it is SOUNDOBJECT
  514. case CEntityProperty::EPT_SOUNDOBJECT:
  515. // write CSoundObject
  516. WriteSoundObject_t(ostrm, PROPERTY(epProperty.ep_slOffset, CSoundObject));
  517. break;
  518. // if it is CPlacement3D
  519. case CEntityProperty::EPT_PLACEMENT3D:
  520. // write CPlacement3D
  521. ostrm.Write_t(&PROPERTY(epProperty.ep_slOffset, CPlacement3D), sizeof(CPlacement3D));
  522. break;
  523. default:
  524. ASSERTALWAYS("Unknown property type");
  525. }
  526. }
  527. }}
  528. }
  529. /////////////////////////////////////////////////////////////////////
  530. // Component management functions
  531. /*
  532. * Obtain the component.
  533. */
  534. void CEntityComponent::Obtain_t(void) // throw char *
  535. {
  536. // if obtained
  537. if (ec_pvPointer!=NULL) {
  538. // just add to CRC
  539. AddToCRCTable();
  540. // do not obtain again
  541. return;
  542. }
  543. INDEX ctUsed = 0;
  544. // check the component type
  545. switch(ec_ectType) {
  546. // if texture
  547. case ECT_TEXTURE:
  548. // obtain texture data
  549. ec_ptdTexture = _pTextureStock->Obtain_t(ec_fnmComponent);
  550. ctUsed = ec_ptdTexture->GetUsedCount();
  551. break;
  552. // if model
  553. case ECT_MODEL:
  554. // obtain model data
  555. ec_pmdModel = _pModelStock->Obtain_t(ec_fnmComponent);
  556. ctUsed = ec_pmdModel->GetUsedCount();
  557. break;
  558. // if sound
  559. case ECT_SOUND:
  560. // obtain sound data
  561. ec_psdSound = _pSoundStock->Obtain_t(ec_fnmComponent);
  562. ctUsed = ec_psdSound->GetUsedCount();
  563. break;
  564. // if class
  565. case ECT_CLASS:
  566. // obtain entity class
  567. ec_pecEntityClass = _pEntityClassStock->Obtain_t(ec_fnmComponent);
  568. ctUsed = ec_pecEntityClass->GetUsedCount();
  569. break;
  570. // if something else
  571. default:
  572. // error
  573. ThrowF_t(TRANS("Component '%s'(%d) is of unknown type!"), (CTString&)ec_fnmComponent, ec_slID);
  574. }
  575. // if not already loaded and should not be precaching now
  576. if( ctUsed<=1 && !_precache_bNowPrecaching) {
  577. // report warning
  578. CPrintF(TRANS("Not precached: (0x%08X)'%s'\n"), this->ec_slID, ec_fnmComponent);
  579. }
  580. //CPrintF(TRANS("Precaching NOW: (0x%08X)'%s'\n"), this->ec_slID, ec_fnmComponent);
  581. // add to CRC
  582. AddToCRCTable();
  583. }
  584. void CEntityComponent::ObtainWithCheck(void)
  585. {
  586. try {
  587. Obtain_t();
  588. } catch(char *strError) {
  589. FatalError("%s", strError);
  590. }
  591. }
  592. // add component to crc table
  593. void CEntityComponent::AddToCRCTable(void)
  594. {
  595. // if not obtained
  596. if (ec_pvPointer==NULL) {
  597. // do nothing
  598. return;
  599. }
  600. // add it
  601. switch(ec_ectType) {
  602. case ECT_TEXTURE: ec_ptdTexture->AddToCRCTable(); break;
  603. case ECT_MODEL: ec_pmdModel->AddToCRCTable(); break;
  604. case ECT_SOUND: ec_psdSound->AddToCRCTable(); break;
  605. case ECT_CLASS: ec_pecEntityClass->AddToCRCTable(); break;
  606. }
  607. }
  608. /*
  609. * Release the component.
  610. */
  611. void CEntityComponent::Release(void)
  612. {
  613. // if the component is not obtained
  614. if (ec_pvPointer==NULL) {
  615. // don't release it
  616. return;
  617. }
  618. // check the component type
  619. switch(ec_ectType) {
  620. // if texture
  621. case ECT_TEXTURE:
  622. // release texture data
  623. _pTextureStock->Release(ec_ptdTexture);
  624. break;
  625. // if model
  626. case ECT_MODEL:
  627. // release model data
  628. _pModelStock->Release(ec_pmdModel);
  629. break;
  630. // if sound
  631. case ECT_SOUND:
  632. // release sound data
  633. _pSoundStock->Release(ec_psdSound);
  634. break;
  635. // if class
  636. case ECT_CLASS:
  637. // release entity class
  638. _pEntityClassStock->Release(ec_pecEntityClass);
  639. break;
  640. // if something else
  641. default:
  642. // error
  643. ThrowF_t(TRANS("Component '%s'(%d) is of unknown type!"), (CTString&)ec_fnmComponent, ec_slID);
  644. }
  645. // released
  646. ec_pvPointer=NULL;
  647. }
  648. // these entity classes are bases, here stop all recursive searches
  649. ENTITY_CLASSDEFINITION_BASE(CEntity, 32000);
  650. ENTITY_CLASSDEFINITION_BASE(CLiveEntity, 32001);
  651. ENTITY_CLASSDEFINITION_BASE(CRationalEntity, 32002);