ShipAliveDetector.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include "ShipAliveDetector.h"
  2. #include "Ships\ship.h"
  3. //============================================================================================
  4. ShipAliveDetector::ShipAliveDetector() :
  5. m_events(_FL_)
  6. {
  7. m_time = -1.0f;
  8. m_delayTime = 0.0f;
  9. m_bWaitTrigger = false;
  10. }
  11. ShipAliveDetector::~ShipAliveDetector()
  12. {
  13. m_events.DelAll();
  14. }
  15. //============================================================================================
  16. //Инициализировать объект
  17. bool ShipAliveDetector::Create(MOPReader & reader)
  18. {
  19. m_time = -1.0f;
  20. m_delayTime = 0.0f;
  21. // тут нечего показывать - это логический объект
  22. Show(false);
  23. // Выбираем объект для слежения
  24. ConstString pcWatchedObjID = reader.String();
  25. FindObject( pcWatchedObjID, m_Object );
  26. if( !m_Object.Ptr() )
  27. {
  28. Mission().LogicDebugError("ShipAliveDetector \"%s\" not created -> AIObject not found", GetObjectID().c_str());
  29. return false;
  30. }
  31. MO_IS_IF_NOT(tid, "Ship", m_Object.Ptr())
  32. {
  33. Mission().LogicDebugError("ShipAliveDetector \"%s\" not created -> AIObject \"%s\" is not \"Ship\"", GetObjectID().c_str(), pcWatchedObjID.c_str());
  34. return false;
  35. }
  36. // Задержка на включение тригера
  37. m_delayTime = reader.Float();
  38. // Инициализируем масссив событий
  39. m_events.DelAll();
  40. long nSize = reader.Array();
  41. m_events.AddElements( nSize );
  42. for( long n=0; n<nSize; n++ )
  43. {
  44. m_events[n].Init(reader);
  45. }
  46. // Сопоставляем тригеры по типам смерти с событиями из массива
  47. if( !ReadDieEventIndexWithCheck(reader, "default", m_nDefaultDie) )
  48. return false;
  49. if( !ReadDieEventIndexWithCheck(reader, "flamethrower", m_nFireDie) )
  50. return false;
  51. if( !ReadDieEventIndexWithCheck(reader, "cannon", m_nCannonDie) )
  52. return false;
  53. if( !ReadDieEventIndexWithCheck(reader, "mine", m_nMineDie) )
  54. return false;
  55. if( !ReadDieEventIndexWithCheck(reader, "ram", m_nRamDie) )
  56. return false;
  57. m_bWaitTrigger = true;
  58. Activate(reader.Bool());
  59. return true;
  60. }
  61. bool ShipAliveDetector::ReadDieEventIndexWithCheck( MOPReader & reader, const char* pcDieTypeName, long& nVal )
  62. {
  63. nVal = reader.Long();
  64. if( nVal < 0 || nVal >= (long)m_events.Size() )
  65. {
  66. Mission().LogicDebugError("ShipAliveDetector \"%s\" not created -> Wrong index for %s die", GetObjectID().c_str(), pcDieTypeName);
  67. return false;
  68. }
  69. return true;
  70. }
  71. //Активировать
  72. void ShipAliveDetector::Activate(bool isActive)
  73. {
  74. MissionObject::Activate(isActive);
  75. if(!EditMode_IsOn())
  76. {
  77. if(IsActive() )
  78. {
  79. if( m_bWaitTrigger )
  80. {
  81. LogicDebug("Activate");
  82. SetUpdate(&ShipAliveDetector::Work, ML_TRIGGERS);
  83. }
  84. else
  85. {
  86. LogicDebug("Activate but object already is dead and triggered");
  87. DelUpdate(&ShipAliveDetector::Work);
  88. }
  89. }else{
  90. LogicDebug("Deactivate");
  91. DelUpdate(&ShipAliveDetector::Work);
  92. }
  93. }else{
  94. DelUpdate(&ShipAliveDetector::Work);
  95. }
  96. }
  97. //============================================================================================
  98. //Работа детектора
  99. void _cdecl ShipAliveDetector::Work(float dltTime, long level)
  100. {
  101. if( !m_bWaitTrigger )
  102. return;
  103. //Проверяем правильность объекта
  104. if( !m_Object.Ptr() ) return;
  105. if( !m_Object.Validate() )
  106. return;
  107. //Если жив
  108. bool bLive = !(m_Object.Ptr()->IsDie() | m_Object.Ptr()->IsDead());
  109. // Только умерли - ставим задержку на тригер смерти
  110. if(!bLive && m_time < -0.5f)
  111. {
  112. m_time = m_delayTime;
  113. LogicDebug("Start timer in time: %f", m_time);
  114. }
  115. // отсчет задержки для тригера смерти
  116. if(m_time > -0.5f)
  117. {
  118. m_time -= dltTime;
  119. if(m_time <= 0.0f)
  120. {
  121. LogicDebug("Triggering");
  122. m_time = -1.0f;
  123. m_bWaitTrigger = false;
  124. Activate(false);
  125. // выбираем евент в зависимости от того как умер корабль
  126. MissionTrigger* pEv = 0;
  127. Ship::DieType dt = ((Ship*)m_Object.Ptr())->GetDieType();
  128. switch( dt )
  129. {
  130. case Ship::DieType_flamethrower: pEv = &m_events[m_nFireDie]; break;
  131. case Ship::DieType_cannon: pEv = &m_events[m_nCannonDie]; break;
  132. case Ship::DieType_mine: pEv = &m_events[m_nMineDie]; break;
  133. case Ship::DieType_ram: pEv = &m_events[m_nRamDie]; break;
  134. default: pEv = &m_events[m_nDefaultDie];
  135. }
  136. if( pEv ) pEv->Activate(Mission(), false);
  137. }
  138. }
  139. }
  140. //============================================================================================
  141. //Параметры инициализации
  142. //============================================================================================
  143. MOP_BEGINLISTCG(ShipAliveDetector, "Ship alive detector", '1.00', 0x0fffffff, "Alive detector look for ship object,\nand triggering if object is dead.", "Logic")
  144. MOP_STRING("Object id", "Player")
  145. MOP_FLOATEXC("Delay time", 0.0f, 0.0f, 100000.0f, "Delay time in seconds before activate trigger")
  146. MOP_ARRAYBEG("Die events", 1, 10)
  147. MOP_MISSIONTRIGGER("")
  148. MOP_ARRAYEND
  149. MOP_LONGC("Die type default", 0, "Index into events array for default die");
  150. MOP_LONGC("Die type flame", 0, "Index into events array for die from falmethrower fire");
  151. MOP_LONGC("Die type cannon", 0, "Index into events array for die from cannon fire");
  152. MOP_LONGC("Die type mine", 0, "Index into events array for die from mine explosion");
  153. MOP_LONGC("Die type ram", 0, "Index into events array for die from ram collision");
  154. MOP_BOOL("Active", true)
  155. MOP_ENDLIST(ShipAliveDetector)