buildingeffectigc.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /*
  2. ** Copyright (C) 1996, 1997 Microsoft Corporation. All Rights Reserved.
  3. **
  4. ** File: buildingEffectIGC.cpp
  5. **
  6. ** Author:
  7. **
  8. ** Description:
  9. ** Implementation of the CclusterIGC class. This file was initially created by
  10. ** the ATL wizard for the core object.
  11. **
  12. ** History:
  13. */
  14. // buildingEffectIGC.cpp : Implementation of buildingEffectIGC
  15. #ifndef __BUILDINGEFFECTIGC_H_
  16. #define __BUILDINGEFFECTIGC_H_
  17. const float c_dtShrink = 10.0f;
  18. const float c_dtOpaque = 10.0f;
  19. const float c_dtGrow = 10.0f;
  20. const float c_dtEnvelope = 10.0f;
  21. class CbuildingEffectIGC : public TmodelIGC<IbuildingEffectIGC>
  22. {
  23. public:
  24. CbuildingEffectIGC(void)
  25. {
  26. }
  27. ~CbuildingEffectIGC(void)
  28. {
  29. }
  30. public:
  31. // IbaseIGC
  32. virtual HRESULT Initialize(ImissionIGC* pMission, Time now, const void* data, int dataSize)
  33. {
  34. TmodelIGC<IbuildingEffectIGC>::Initialize(pMission, now, data, dataSize);
  35. {
  36. ZRetailAssert (data && (dataSize > sizeof(DataBuildingEffectBase)));
  37. DataBuildingEffectBase* dataBuilding = (DataBuildingEffectBase*)data;
  38. m_positionStart = dataBuilding->positionStart;
  39. m_positionStop = dataBuilding->positionStop;
  40. m_radiusAsteroid = dataBuilding->radiusAsteroid;
  41. m_radiusStation = dataBuilding->radiusStation;
  42. m_timeEnvelope = pMission->GetIgcSite()->ClientTimeFromServerTime(dataBuilding->timeStart);
  43. m_timeGrow = m_timeEnvelope + c_dtEnvelope;
  44. m_timeOpaque = m_timeGrow + c_dtGrow;
  45. m_timeShrink = m_timeOpaque + c_dtOpaque;
  46. m_timeComplete = m_timeShrink + c_dtShrink;
  47. }
  48. assert (sizeof(DataBuildingEffectIGC) != sizeof(DataBuildingEffectExport));
  49. IclusterIGC* pcluster;
  50. const Color* pcolor;
  51. if (dataSize == sizeof(DataBuildingEffectIGC))
  52. {
  53. DataBuildingEffectIGC* dataBuilding = (DataBuildingEffectIGC*)data;
  54. m_pshipBuilder = dataBuilding->pshipBuilder;
  55. assert (m_pshipBuilder);
  56. m_pshipBuilder->SetStateM(drillingMaskIGC | buildingMaskIGC);
  57. m_pside = m_pshipBuilder->GetSide();
  58. m_pstationType = (IstationTypeIGC*)(m_pshipBuilder->GetBaseData());
  59. m_pasteroid = dataBuilding->pasteroid;
  60. assert (m_pasteroid);
  61. m_pasteroid->SetBuildingEffect(this);
  62. pcluster = dataBuilding->pcluster;
  63. pcolor = &(m_pshipBuilder->GetSide()->GetColor());
  64. }
  65. else
  66. {
  67. ZRetailAssert (dataSize == sizeof(DataBuildingEffectExport));
  68. DataBuildingEffectExport* dataBuilding = (DataBuildingEffectExport*)data;
  69. pcluster = pMission->GetCluster(dataBuilding->clusterID);
  70. m_pasteroid = pcluster->GetAsteroid(dataBuilding->asteroidID);
  71. assert (m_pasteroid);
  72. m_pasteroid->SetBuildingEffect(this);
  73. pcolor = &(dataBuilding->color);
  74. }
  75. LoadEffect(Color(50.0f/255.0f, 28.0f/255.0f, 146.0f/255.0f), //*pcolor,
  76. (c_mtNotPickable | c_mtCastRay | c_mtHitable | c_mtDamagable | c_mtPredictable));
  77. m_radiusMax = 1.1f * (m_radiusAsteroid > m_radiusStation ? m_radiusAsteroid : m_radiusStation);
  78. SetRadius(1.0f);
  79. SetPosition(m_positionStart);
  80. GetHitTest()->SetNoHit(m_pasteroid->GetHitTest());
  81. assert (GetVelocity().LengthSquared() == 0.0f);
  82. assert (pcluster);
  83. SetCluster(pcluster);
  84. //Set the BB's effect, since it was probably created as a result of a collision.
  85. SetBB(now, now, 0.0f);
  86. return S_OK;
  87. }
  88. virtual void Terminate(void)
  89. {
  90. AddRef();
  91. if (m_pasteroid)
  92. {
  93. m_pasteroid->SetBuildingEffect(NULL);
  94. m_pasteroid = NULL;
  95. }
  96. if (m_pshipBuilder)
  97. {
  98. GetMyMission()->GetIgcSite()->KillShipEvent(GetMyLastUpdate(), m_pshipBuilder, NULL,
  99. 0.0f, m_pshipBuilder->GetPosition(), Vector::GetZero());
  100. m_pshipBuilder = NULL;
  101. }
  102. m_pside = NULL;
  103. m_pstationType = NULL;
  104. TmodelIGC<IbuildingEffectIGC>::Terminate();
  105. Release();
  106. }
  107. int Export(void* data) const
  108. {
  109. if (data)
  110. {
  111. DataBuildingEffectExport* pdbe = (DataBuildingEffectExport*)data;
  112. pdbe->timeStart = GetMyMission()->GetIgcSite()->ServerTimeFromClientTime(m_timeEnvelope);
  113. pdbe->asteroidID = m_pasteroid ? m_pasteroid->GetObjectID() : NA;
  114. pdbe->clusterID = GetCluster()->GetObjectID();
  115. pdbe->radiusAsteroid = m_radiusAsteroid;
  116. pdbe->radiusStation = m_radiusStation;
  117. pdbe->positionStart = m_positionStart;
  118. pdbe->positionStop = m_positionStop;
  119. assert (m_pshipBuilder);
  120. pdbe->color = m_pshipBuilder->GetSide()->GetColor();
  121. }
  122. return sizeof(DataBuildingEffectExport);
  123. }
  124. virtual void Update(Time now)
  125. {
  126. if (now >= m_timeComplete)
  127. {
  128. Terminate();
  129. }
  130. else
  131. {
  132. Vector position;
  133. float radius;
  134. float aInner;
  135. float fInner;
  136. float fOuter;
  137. if (now >= m_timeShrink)
  138. {
  139. float f = (now - m_timeShrink) / c_dtShrink;
  140. position = m_positionStop;
  141. radius = m_radiusStation * f + m_radiusMax * (1.0f - f);
  142. aInner = 1.0f - f;
  143. fInner = 1.0f - f;
  144. fOuter = 1.0f - f;
  145. }
  146. else if (now >= m_timeOpaque)
  147. {
  148. float f = (now - m_timeOpaque) / c_dtOpaque;
  149. position = m_positionStop;
  150. radius = m_radiusMax;
  151. aInner = 0.5f + 0.5f * f;
  152. fInner = 1.0f;
  153. fOuter = 1.0f;
  154. }
  155. else if (now >= m_timeGrow)
  156. {
  157. float f = (now - m_timeGrow) / c_dtGrow;
  158. position = m_positionStop;
  159. radius = m_radiusMax * f + m_radiusAsteroid * (1.0f - f);
  160. aInner = 0.5f;
  161. fInner = 1.0f;
  162. fOuter = 1.0f;
  163. }
  164. else
  165. {
  166. float dt = (now - m_timeEnvelope);
  167. float f = (dt > 0.0f) ? (dt / c_dtEnvelope) : 0.0f;
  168. position = m_positionStop * f + m_positionStart * (1.0f - f);
  169. radius = f * m_radiusAsteroid + 1.0f - f;
  170. aInner = 0.5f;
  171. fInner = 1.0f;
  172. fOuter = 1.0f;
  173. }
  174. SetPosition(position);
  175. SetRadius(radius);
  176. assert (GetThingSite());
  177. GetThingSite()->SetColors(aInner, fInner, fOuter);
  178. }
  179. }
  180. virtual ObjectType GetObjectType(void) const
  181. {
  182. return OT_buildingEffect;
  183. }
  184. // ImodelIGC
  185. virtual void SetCluster(IclusterIGC* cluster)
  186. {
  187. AddRef();
  188. {
  189. IclusterIGC* c = GetCluster();
  190. if (c)
  191. c->DeleteModel(this);
  192. }
  193. TmodelIGC<IbuildingEffectIGC>::SetCluster(cluster);
  194. if (cluster)
  195. cluster->AddModel(this);
  196. Release();
  197. }
  198. virtual void HandleCollision(Time timeCollision,
  199. float tCollision,
  200. const CollisionEntry& entry,
  201. ImodelIGC* pModel)
  202. {
  203. ObjectType type = pModel->GetObjectType();
  204. if ((type != OT_buildingEffect) &&
  205. (type != OT_asteroid) &&
  206. (type != OT_station) &&
  207. (type != OT_probe))
  208. {
  209. pModel->HandleCollision(timeCollision, tCollision, entry, this);
  210. }
  211. }
  212. // IdamageIGC
  213. virtual DamageResult ReceiveDamage(DamageTypeID type,
  214. float amount,
  215. Time timeCollision,
  216. const Vector& position1,
  217. const Vector& position2,
  218. ImodelIGC* launcher)
  219. {
  220. if (m_pasteroid)
  221. {
  222. m_pasteroid->ReceiveDamage(type, amount, timeCollision, m_pasteroid->GetPosition(), position2, launcher);
  223. }
  224. return c_drNoDamage;
  225. }
  226. virtual float GetFraction(void) const
  227. {
  228. return 1.0f;
  229. }
  230. virtual void SetFraction(float newVal)
  231. {
  232. }
  233. virtual float GetHitPoints(void) const
  234. {
  235. return m_pasteroid ? m_pasteroid->GetHitPoints() : 1.0f;
  236. }
  237. // IbuildingEffectIGC
  238. virtual void BuilderTerminated(void)
  239. {
  240. m_pshipBuilder = NULL;
  241. }
  242. virtual IasteroidIGC* GetAsteroid(void) const
  243. {
  244. return m_pasteroid;
  245. }
  246. virtual void MakeUnhitable(void)
  247. {
  248. assert (m_pasteroid);
  249. m_pasteroid = NULL;
  250. TmodelIGC<IbuildingEffectIGC>::MakeUnhitable(); //Virtual wrapper for a non-virtual function
  251. }
  252. virtual void AsteroidUpdate(Time now)
  253. {
  254. if ((now >= m_timeShrink) && m_pshipBuilder)
  255. {
  256. //transform the asteroid into the station
  257. assert (m_pstationType);
  258. assert (m_pside);
  259. GetMyMission()->GetIgcSite()->SendChatf(m_pshipBuilder, CHAT_TEAM, m_pside->GetObjectID(),
  260. m_pstationType->GetCompletionSound(),
  261. "Finished building %s", m_pstationType->GetName());
  262. //Quietly kill the ship (after nuking its parts to prevent treasure from being created)
  263. {
  264. const PartListIGC* parts = m_pshipBuilder->GetParts();
  265. PartLinkIGC* plink;
  266. while (plink = parts->first()) //Not ==
  267. plink->data()->Terminate();
  268. }
  269. m_pshipBuilder->SetAmmo(0);
  270. m_pshipBuilder->SetFuel(0.0f);
  271. m_pshipBuilder->SetStateM(0);
  272. GetMyMission()->GetIgcSite()->KillShipEvent(now, m_pshipBuilder, NULL, 0.0f, m_pshipBuilder->GetPosition(), Vector::GetZero());
  273. m_pshipBuilder = NULL;
  274. IasteroidIGC* pasteroid = m_pasteroid;
  275. m_pasteroid->SetBuildingEffect(NULL); //Clear the building effect so it isn't nuked along with the asteroid
  276. assert (m_pasteroid == NULL);
  277. GetMyMission()->GetIgcSite()->BuildStation(pasteroid,
  278. m_pside,
  279. m_pstationType,
  280. now);
  281. }
  282. }
  283. private:
  284. TRef<IshipIGC> m_pshipBuilder;
  285. TRef<IasteroidIGC> m_pasteroid;
  286. TRef<IstationTypeIGC> m_pstationType;
  287. TRef<IsideIGC> m_pside;
  288. Time m_timeComplete;
  289. Time m_timeShrink;
  290. Time m_timeOpaque;
  291. Time m_timeGrow;
  292. Time m_timeEnvelope;
  293. Vector m_positionStart;
  294. Vector m_positionStop;
  295. float m_radiusAsteroid;
  296. float m_radiusStation;
  297. float m_radiusMax;
  298. };
  299. #endif