treasureIGC.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. ** Copyright (C) 1996, 1997 Microsoft Corporation. All Rights Reserved.
  3. **
  4. ** File: treasureIGC.cpp
  5. **
  6. ** Author:
  7. **
  8. ** Description:
  9. ** Implementation of the CtreasureIGC class. This file was initially created by
  10. ** the ATL wizard.
  11. **
  12. ** History:
  13. */
  14. // treasureIGC.cpp : Implementation of CtreasureIGC
  15. #include "pch.h"
  16. #include "treasureIGC.h"
  17. #include <stdio.h>
  18. const float c_deceleration = 10.0f;
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CtreasureIGC
  21. HRESULT CtreasureIGC::Initialize(ImissionIGC* pMission, Time now, const void* data, int dataSize)
  22. {
  23. //Does this treasure already exist? If so, abort which will prevent it from being terminated
  24. if (pMission->GetTreasure(((DataTreasureIGC*)data)->objectID))
  25. return E_ABORT;
  26. ZRetailAssert (data && (dataSize == sizeof(DataTreasureIGC)));
  27. {
  28. DataTreasureIGC* dataTreasure = (DataTreasureIGC*)data;
  29. m_data = *dataTreasure;
  30. m_data.createNow = false;
  31. if (dataTreasure->createNow)
  32. {
  33. m_data.time0 = now;
  34. }
  35. else
  36. {
  37. m_data.time0 = pMission->GetIgcSite()->ClientTimeFromServerTime(m_data.time0);
  38. }
  39. TmodelIGC<ItreasureIGC>::Initialize(pMission, now, &m_data, sizeof(m_data));
  40. if (m_data.treasureCode == c_tcPart)
  41. {
  42. IpartTypeIGC* pt = pMission->GetPartType(m_data.treasureID);
  43. assert (pt);
  44. m_buyable = (IbuyableIGC*)(pt);
  45. if (m_data.amount == NA)
  46. {
  47. switch (pt->GetEquipmentType())
  48. {
  49. case ET_Dispenser:
  50. case ET_ChaffLauncher:
  51. case ET_Magazine:
  52. {
  53. m_data.amount = randomInt(1, pt->GetAmount(NULL));
  54. }
  55. break;
  56. case ET_Pack:
  57. {
  58. short a = ((DataPackTypeIGC*)(pt->GetData()))->amount;
  59. assert (a > 2);
  60. m_data.amount = randomInt(a/2, a);
  61. }
  62. break;
  63. default:
  64. m_data.amount = 0;
  65. }
  66. }
  67. assert (m_buyable);
  68. m_buyable->AddRef();
  69. }
  70. else if (m_data.treasureCode == c_tcDevelopment)
  71. {
  72. m_buyable = (IbuyableIGC*)(pMission->GetDevelopment(m_data.treasureID));
  73. assert (m_buyable);
  74. m_buyable->AddRef();
  75. }
  76. else
  77. {
  78. m_buyable = NULL;
  79. if (m_data.treasureCode == c_tcCash)
  80. m_data.amount = m_data.treasureID;
  81. }
  82. Vector p0;
  83. const Vector* pposition;
  84. const Vector* pvelocity;
  85. m_speed0 = m_data.v0.Length();
  86. m_stationaryF = (m_speed0 == 0.0f);
  87. {
  88. float dt = now - m_data.time0;
  89. if (m_speed0 <= c_deceleration * dt)
  90. {
  91. //drifted to a stop
  92. m_stationaryF = true;
  93. p0 = m_data.p0 + m_data.v0 * (0.5f * m_speed0 / c_deceleration);
  94. pposition = &p0;
  95. pvelocity = &(Vector::GetZero());
  96. }
  97. else
  98. {
  99. pposition = &(m_data.p0);
  100. pvelocity = &(m_data.v0);
  101. }
  102. }
  103. static const char* cName = "acs14";
  104. const char* name;
  105. const char* texture = NULL;
  106. const char* icon;
  107. if (m_buyable)
  108. {
  109. name = m_buyable->GetModelName();
  110. icon = m_buyable->GetIconName();
  111. }
  112. else if (m_data.treasureCode == c_tcFlag)
  113. {
  114. if (m_data.treasureID != SIDE_TEAMLOBBY)
  115. {
  116. name = NULL;
  117. texture = "biosflag";
  118. icon = "flag";
  119. SetName("Flag");
  120. IsideIGC* pside = pMission->GetSide(m_data.treasureID);
  121. assert (pside);
  122. SetSide(pside);
  123. }
  124. else
  125. {
  126. name = "artifact";
  127. icon = "articon";
  128. SetName("Artifact");
  129. }
  130. SetSignature(1.5f);
  131. }
  132. else
  133. {
  134. assert ((m_data.treasureCode == c_tcCash) || (m_data.treasureCode == c_tcPowerup));
  135. name = cName;
  136. icon = (m_data.treasureCode == c_tcCash) ? "cashicon" : "iconpu";
  137. }
  138. if (texture)
  139. {
  140. HRESULT rc = LoadDecal(texture, icon,
  141. Color(1.0f,
  142. 1.0f,
  143. 1.0f,
  144. 1.0f),
  145. false,
  146. 1.0f,
  147. m_stationaryF
  148. ? (c_mtStatic | c_mtHitable | c_mtSeenBySide | c_mtPredictable)
  149. : (c_mtCastRay | c_mtSeenBySide | c_mtPredictable));
  150. assert (SUCCEEDED(rc));
  151. }
  152. else
  153. {
  154. HRESULT rc = Load(0, name, texture, icon,
  155. m_stationaryF
  156. ? (c_mtStatic | c_mtHitable | c_mtSeenBySide | c_mtPredictable)
  157. : (c_mtCastRay | c_mtSeenBySide | c_mtPredictable));
  158. assert (SUCCEEDED(rc));
  159. Orientation o;
  160. Rotation r;
  161. //Parts get a random orientation
  162. o.Set(Vector::RandomDirection());
  163. //and a random rotation
  164. r.axis(Vector::RandomDirection());
  165. r.angle(random(-6, 6));
  166. SetOrientation(o);
  167. SetRotation(r);
  168. }
  169. SetRadius(5.0f); //NYI -- needs to be gotten from the DB
  170. SetMass(0.0f);
  171. m_expire = m_data.time0 + m_data.lifespan;
  172. SetPosition(*pposition);
  173. SetVelocity(*pvelocity);
  174. SetCluster(pMission->GetCluster(m_data.clusterID));
  175. pMission->AddTreasure(this);
  176. //Fun and games time ... treasures can be created in the cluster update
  177. //so initialize everything as if we were in the resolve collisions part
  178. //of the cluster update before adding the object to the cluster.
  179. //Fortunately, the KD tree is no longer used in the update by this point
  180. //and all we need to do is set the bounding box
  181. SetBB(now, now, 0.0f);
  182. }
  183. return S_OK;
  184. }
  185. void CtreasureIGC::Update(Time now)
  186. {
  187. if (now >= m_expire)
  188. GetMyMission()->GetIgcSite()->KillTreasureEvent(this);
  189. else
  190. {
  191. if ((!m_stationaryF) && (now > m_data.time0))
  192. {
  193. float dt1 = GetMyLastUpdate() - m_data.time0;
  194. float v1 = m_speed0 - c_deceleration * dt1;
  195. if (v1 <= 0.0f)
  196. {
  197. //The object came, previously, to a complete stop
  198. m_stationaryF = true;
  199. SetPosition(m_data.p0 + m_data.v0 * (0.5f * m_speed0 / c_deceleration));
  200. SetVelocity(Vector::GetZero());
  201. MakeStatic();
  202. }
  203. else
  204. {
  205. //Still moving ... calculate the object's position at the start and stop
  206. assert (m_speed0 != 0.0f);
  207. Vector p1 = m_data.p0 +
  208. m_data.v0 *
  209. (dt1 - 0.5f * dt1 * dt1 * c_deceleration / m_speed0);
  210. SetPosition(p1);
  211. if (now == GetMyLastUpdate())
  212. {
  213. SetVelocity(m_data.v0 * (v1 / m_speed0));
  214. }
  215. else
  216. {
  217. float dt2 = now - m_data.time0;
  218. float v2 = m_speed0 - c_deceleration * dt2;
  219. Vector p2 = (v2 > 0.0f)
  220. ? (m_data.p0 +
  221. m_data.v0 *
  222. (dt2 - 0.5f * dt2 * dt2 * c_deceleration / m_speed0))
  223. : (m_data.p0 + m_data.v0 * (0.5f * m_speed0 / c_deceleration));
  224. SetVelocity((p2 - p1) / (now - GetMyLastUpdate()));
  225. }
  226. }
  227. }
  228. TmodelIGC<ItreasureIGC>::Update(now);
  229. }
  230. }
  231. int CtreasureIGC::Export(void* data) const
  232. {
  233. if (data)
  234. {
  235. DataTreasureIGC* dataTreasure = (DataTreasureIGC*)data;
  236. *dataTreasure = m_data;
  237. dataTreasure->time0 = GetMyMission()->GetIgcSite()->ServerTimeFromClientTime(m_data.time0);
  238. }
  239. return sizeof(DataTreasureIGC);
  240. }