mineigc.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. ** Copyright (C) 1996, 1997 Microsoft Corporation. All Rights Reserved.
  3. **
  4. ** File: mineIGC.h
  5. **
  6. ** Author:
  7. **
  8. ** Description:
  9. ** Header for the CmineIGC class. This file was initially created by
  10. ** the ATL wizard.
  11. **
  12. ** History:
  13. */
  14. // mineIGC.h : Declaration of the CmineIGC
  15. #ifndef __MINEIGC_H_
  16. #define __MINEIGC_H_
  17. #include "modelIGC.h"
  18. const char c_msStart = 0;
  19. const char c_msExploded = 1;
  20. const char c_msScattered = 2;
  21. class CmineIGC : public TmodelIGC<ImineIGC>
  22. {
  23. public:
  24. CmineIGC(void);
  25. ~CmineIGC(void);
  26. public:
  27. // IbaseIGC
  28. virtual HRESULT Initialize(ImissionIGC* pMission, Time now, const void* data, int dataSize);
  29. virtual void Terminate(void);
  30. virtual void Update(Time now);
  31. virtual int Export(void* data) const;
  32. virtual ObjectType GetObjectType(void) const
  33. {
  34. return OT_mine;
  35. }
  36. virtual ObjectID GetObjectID(void) const
  37. {
  38. return m_mineID;
  39. }
  40. // ImodelIGC
  41. virtual void SetCluster(IclusterIGC* cluster)
  42. {
  43. AddRef();
  44. {
  45. IclusterIGC* c = GetCluster();
  46. if (c)
  47. c->DeleteMine(this);
  48. }
  49. TmodelIGC<ImineIGC>::SetCluster(cluster);
  50. if (cluster)
  51. cluster->AddMine(this);
  52. Release();
  53. }
  54. virtual void HandleCollision(Time timeCollision,
  55. float tCollision,
  56. const CollisionEntry& entry,
  57. ImodelIGC* pmodel)
  58. {
  59. if (pmodel->GetObjectType() == OT_ship)
  60. {
  61. const float c_dtArmTime = 1.0f;
  62. if ((pmodel->GetSide() != GetSide()) && (timeCollision >= m_time0 + c_dtArmTime))
  63. {
  64. //Find the length of the ship's path within the minefield
  65. const Vector& dV = pmodel->GetVelocity();
  66. double a = dV * dV;
  67. if (a > 1.0) //ya got to be moving at least a little to get nailed
  68. {
  69. const Vector& pMe = GetPosition();
  70. const Vector& pHim = pmodel->GetPosition();
  71. Vector pEnter = pHim + tCollision * dV;
  72. //What time do we leave the minefield?
  73. //R^2(t) = |pHim + t * vHim - pMe|^2 = (myRadius + hisRadius)^2
  74. Vector dP = pMe - pHim; //Note: sense is reversed wrt dV to eliminate a - sign below
  75. float rMe = GetRadius();
  76. float rHim = pmodel->GetRadius();
  77. double r = rMe + rHim;
  78. double halfB = dP * dV;
  79. double c = dP * dP - r * r;
  80. double b2ac = halfB * halfB - a * c;
  81. if (b2ac >= 0.0f)
  82. {
  83. double s = sqrt(b2ac);
  84. float tExit = (float)((halfB + s) / a);
  85. float tStop = GetHitTest()->GetTstop();
  86. if (tExit > tStop)
  87. tExit = tStop;
  88. float dt = tExit - tCollision;
  89. if (dt > 0.0f)
  90. {
  91. const float c_damageMultiplier = 1.0f / (5.0f * 5.0f * 100.0f);
  92. float speed2 = float(a);
  93. float amount = dt * speed2 * m_mineType->GetPower() * rHim * rHim * c_damageMultiplier / (2.0f * rMe);
  94. float endurance = m_mineType->GetEndurance();
  95. float oldEndurance = endurance * m_fraction;
  96. float newEndurance = oldEndurance * float(exp(-amount / endurance));
  97. float damage = oldEndurance - newEndurance;
  98. m_fraction = newEndurance / endurance;
  99. Vector position1 = pHim + dV * tCollision;
  100. const float c_radiusPlacement = 10.0f;
  101. Vector position2 = position1 + dV * ((c_radiusPlacement + rHim) / float(sqrt(a))) + Vector::RandomPosition(c_radiusPlacement);
  102. ((IshipIGC*)pmodel)->AddMineDamage(m_mineType->GetDamageType(), damage, timeCollision,
  103. m_launcher,
  104. position1,
  105. position2);
  106. if (newEndurance < 1.0f)
  107. GetMyMission()->GetIgcSite()->KillMineEvent(this);
  108. else
  109. GetThingSite()->SetMineStrength(m_fraction);
  110. }
  111. }
  112. }
  113. }
  114. }
  115. }
  116. // ImineIGC
  117. virtual ImineTypeIGC* GetMineType(void) const
  118. {
  119. return m_mineType;
  120. }
  121. virtual IshipIGC* GetLauncher(void) const
  122. {
  123. return m_launcher;
  124. }
  125. virtual void SetCreateNow (void)
  126. {
  127. m_bCreateNow = true;
  128. }
  129. virtual float GetStrength(void) const
  130. {
  131. return m_fraction;
  132. }
  133. virtual void ReduceStrength(float amount)
  134. {
  135. float endurance = m_mineType->GetEndurance();
  136. float newEndurance = endurance * m_fraction * float(exp(-amount / endurance));
  137. m_fraction = (newEndurance / endurance);
  138. if (m_fraction < 0.25f)
  139. GetMyMission()->GetIgcSite()->KillMineEvent(this);
  140. else
  141. GetThingSite()->SetMineStrength(m_fraction);
  142. }
  143. virtual float GetTimeFraction(void) const
  144. {
  145. Time timeNow = GetMyLastUpdate();
  146. float f = (m_timeExpire - timeNow) / (m_timeExpire - m_time0);
  147. if (f < 0.0f)
  148. f = 0.0f;
  149. else if (f > 1.0f)
  150. f = 1.0f;
  151. return f;
  152. }
  153. private:
  154. ImineTypeIGC* m_mineType;
  155. IshipIGC* m_launcher;
  156. Time m_time0;
  157. Time m_timeExpire;
  158. float m_fraction;
  159. MineID m_mineID;
  160. bool m_bCreateNow;
  161. };
  162. #endif //__MINEIGC_H_