AcceptDetector.cpp 6.4 KB

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