SphereDetector.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. //===========================================================================================================================
  2. // Spirenkov Maxim, 2003
  3. //===========================================================================================================================//
  4. // Mission objects
  5. //===========================================================================================================================
  6. // SphereDetector
  7. //============================================================================================
  8. #include "SphereDetector.h"
  9. //============================================================================================
  10. SphereDetector::SphereDetector()
  11. {
  12. }
  13. SphereDetector::~SphereDetector()
  14. {
  15. }
  16. //============================================================================================
  17. //Инициализировать объект
  18. bool SphereDetector::Create(MOPReader & reader)
  19. {
  20. target.Reset();
  21. isDown = false;
  22. if(!DetectorObject::Create(reader)) return false;
  23. //Получим идентификатор объекта
  24. targetID = reader.String();
  25. //Получить позицию
  26. iniPos = sphere.pos = reader.Position();
  27. //Получить радиус
  28. sphere.radius = reader.Float();
  29. //Имя отсылаемого события
  30. event.Init(reader);
  31. //Активация
  32. Activate(reader.Bool());
  33. //Сбрасывать ли состояние после срабатывания
  34. autoReset = reader.Bool();
  35. //Объект перемещения цели
  36. connectID = reader.String();
  37. FindObject(connectID, connect);
  38. if(connect.Validate())
  39. {
  40. sphere.pos = connect.Ptr()->GetMatrix(Matrix()).pos;
  41. }
  42. return UpdateTarget();
  43. }
  44. //Получить матрицу объекта
  45. Matrix & SphereDetector::GetMatrix(Matrix & mtx)
  46. {
  47. return mtx.BuildPosition(sphere.pos);
  48. }
  49. //Инициализировать объект
  50. bool SphereDetector::EditMode_Create(MOPReader & reader)
  51. {
  52. isDown = false;
  53. if(!DetectorObject::Create(reader)) return false;
  54. SetUpdate(&SphereDetector::EditModeWork, ML_ALPHA5);
  55. Create(reader);
  56. highlight = 0.0f;
  57. resetTime = 0.0f;
  58. return true;
  59. }
  60. //Обновить параметры
  61. bool SphereDetector::EditMode_Update(MOPReader & reader)
  62. {
  63. Create(reader);
  64. return true;
  65. }
  66. //Получить размеры описывающего ящика
  67. void SphereDetector::EditMode_GetSelectBox(Vector & min, Vector & max)
  68. {
  69. min = -sphere.radius - 0.1f;
  70. max = sphere.radius + 0.1f;
  71. }
  72. //Активация детектора
  73. void SphereDetector::ActivateDetector(const char * initiatorID)
  74. {
  75. if(!EditMode_IsOn())
  76. {
  77. LogicDebug("Triggering");
  78. event.Activate(Mission(), false);
  79. }
  80. }
  81. //Активировать
  82. void SphereDetector::Activate(bool isActive)
  83. {
  84. DetectorObject::Activate(isActive);
  85. if(IsActive())
  86. {
  87. LogicDebug("Activate");
  88. SetUpdate(&SphereDetector::Work, ML_TRIGGERS);
  89. }else{
  90. LogicDebug("Deactivate");
  91. DelUpdate(&SphereDetector::Work);
  92. }
  93. }
  94. //============================================================================================
  95. //Работа детектора
  96. void _cdecl SphereDetector::Work(float dltTime, long level)
  97. {
  98. if(!target.Validate())
  99. {
  100. target.Reset();
  101. return;
  102. }
  103. //Отработали и не сами себя востанавливаем - неработаем
  104. if(isDown && !autoReset) return;
  105. //Не активны - не работаем
  106. if(!IsActive()) return;
  107. //Обновляем позицию
  108. if(connect.Validate())
  109. {
  110. sphere.pos = connect.Ptr()->GetMatrix(Matrix()).pos;
  111. }else{
  112. sphere.pos = iniPos;
  113. connect.Reset();
  114. }
  115. //Анализируем
  116. Matrix mtx;
  117. target.Ptr()->GetMatrix(mtx);
  118. //Проверяем пересечение сферы с отрезком
  119. //isDown = sphere.Intersection(targetPos, mtx.pos);
  120. isDown = sphere.Intersection(mtx.pos);
  121. targetPos = mtx.pos;
  122. if(isDown)
  123. {
  124. if(!EditMode_IsOn())
  125. {
  126. ActivateDetector(target.Ptr()->GetObjectID().c_str());
  127. }else{
  128. highlight = 1.0f;
  129. resetTime = 4.0f;
  130. }
  131. }
  132. }
  133. //Работа детектора в режиме редактирования
  134. void _cdecl SphereDetector::EditModeWork(float dltTime, long level)
  135. {
  136. if(!Mission().EditMode_IsAdditionalDraw()) return;
  137. if(!EditMode_IsVisible()) return;
  138. //Обновляем позицию
  139. if(!connect.Validate())
  140. {
  141. if(connectID.NotEmpty())
  142. {
  143. FindObject(connectID, connect);
  144. }
  145. if(connect.Validate())
  146. {
  147. sphere.pos = connect.Ptr()->GetMatrix(Matrix()).pos;
  148. }else{
  149. sphere.pos = iniPos;
  150. connect.Reset();
  151. }
  152. }
  153. //Работа детектора
  154. Work(dltTime, level);
  155. //Обновляем состояние
  156. highlight -= dltTime;
  157. if(highlight < 0.0f) highlight = 0.0f;
  158. if(isDown)
  159. {
  160. resetTime -= dltTime;
  161. if(resetTime <= 0.0f)
  162. {
  163. isDown = false;
  164. resetTime = 0.0f;
  165. }
  166. }
  167. //Проверяем наличие объекта
  168. if(!target.Validate())
  169. {
  170. UpdateTarget();
  171. }
  172. //Выбираем цвет
  173. Color clr;
  174. if(target.Validate())
  175. {
  176. if(IsActive())
  177. {
  178. if(!isDown)
  179. {
  180. clr = Color(0.0f, 0.8f, 0.0f, 0.8f);
  181. }else{
  182. clr = Color(0.8f, 0.0f, 0.0f, 0.8f);
  183. }
  184. }else{
  185. clr = Color(0.8f, 0.8f, 0.8f, 0.5f);
  186. }
  187. }else{
  188. clr = Color(1.0f, 0.0f, 1.0f, 0.8f);
  189. }
  190. clr += highlight;
  191. clr.Clamp();
  192. dword dclr = clr.GetDword();
  193. //Рисуем
  194. Render().DrawSphere(sphere.pos, sphere.radius, dclr, "ShowDetector");
  195. if(EditMode_IsSelect())
  196. {
  197. Render().Print(sphere.pos, -1.0f, -1.0f, 0xffffffff, "Object id: %s", GetObjectID().c_str());
  198. Render().Print(sphere.pos, -1.0f, 0.0f, 0xffffffff, "Target: %s", targetID.c_str());
  199. Render().Print(sphere.pos, -1.0f, 1.0f, 0xffffffff, IsActive() ? "State: on" : "State: off");
  200. }
  201. }
  202. //Обновить цель
  203. bool SphereDetector::UpdateTarget()
  204. {
  205. if(!FindObject(targetID, target)) return false;
  206. Matrix mtx(true);
  207. target.Ptr()->GetMatrix(mtx);
  208. targetPos = mtx.pos;
  209. return true;
  210. }
  211. //============================================================================================
  212. //Параметры инициализации
  213. //============================================================================================
  214. MOP_BEGINLISTCG(SphereDetector, "Sphere detector", '1.00', 0x0fffffff, "Detector triggering if mission object enter or leave in sphere.", "Logic")
  215. MOP_STRING("Object id", "Player")
  216. MOP_POSITION("Position", Vector(0.0f))
  217. MOP_FLOATEX("Radius", 1.0f, 0.001f, 1000000.0f)
  218. MOP_MISSIONTRIGGERG("Events", "")
  219. MOP_BOOL("Active", true)
  220. MOP_BOOL("Auto reset", false)
  221. MOP_STRING("Connect to object", "")
  222. MOP_ENDLIST(SphereDetector)