Synchronizer.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. //===========================================================================================================================
  2. // Spirenkov Maxim, 2003
  3. //===========================================================================================================================//
  4. // Mission objects
  5. //===========================================================================================================================
  6. // Synchronizer
  7. //============================================================================================
  8. #include "Synchronizer.h"
  9. #include "MissionReloader.h"
  10. const Synchronizer::Logic Synchronizer::logics[] =
  11. {
  12. {ConstString("All at one time"), &Synchronizer::LogicAll},
  13. {ConstString("One at one time (random)"), &Synchronizer::LogicRand},
  14. {ConstString("One at one time (first)"), &Synchronizer::LogicFirst},
  15. };
  16. //============================================================================================
  17. Synchronizer::Synchronizer() : events(_FL_)
  18. {
  19. logicIndex = -1;
  20. }
  21. Synchronizer::~Synchronizer()
  22. {
  23. }
  24. //============================================================================================
  25. //Инициализировать объект
  26. bool Synchronizer::Create(MOPReader & reader)
  27. {
  28. events.DelAll();
  29. ConstString type = reader.Enum();
  30. logicIndex = -1;
  31. for(long i = 0; i < ARRSIZE(logics); i++)
  32. {
  33. if(type == logics[i].name)
  34. {
  35. logicIndex = i;
  36. break;
  37. }
  38. }
  39. Assert(logicIndex >= 0);
  40. long count = reader.Array();
  41. for(long i = 0; i < count; i++)
  42. {
  43. Event & evt = events[events.Add()];
  44. evt.name = reader.String();
  45. evt.event.Init(reader);
  46. evt.state = false;
  47. }
  48. tick.Init(reader);
  49. Activate(reader.Bool());
  50. return true;
  51. }
  52. //Обработчик команд для объекта
  53. void Synchronizer::Command(const char * id, dword numParams, const char ** params)
  54. {
  55. if(!id) return;
  56. ConstString cid(id);
  57. static const ConstString reset("reset");
  58. if(cid == reset)
  59. {
  60. for(long i = 0; i < events; i++)
  61. {
  62. events[i].state = false;
  63. events[i].event.Reset();
  64. }
  65. LogicDebug("Reseting...");
  66. return;
  67. }
  68. if(!IsActive()) return;
  69. //Тик
  70. static const ConstString ctick("tick");
  71. if(cid == ctick)
  72. {
  73. LogicDebug("Tick event...");
  74. LogicDebugLevel(true);
  75. if(logicIndex >= 0)
  76. {
  77. LogicDebug("Logic: \"%s\"", logics[logicIndex].name.c_str());
  78. (this->*logics[logicIndex].logic)();
  79. }
  80. LogicDebugLevel(false);
  81. tick.Activate(Mission(), false);
  82. return;
  83. }
  84. //Если ошибочны параметры - скипаем
  85. if(!numParams || !params[0])
  86. {
  87. LogicDebug("Synchronizer -> invalidate event name: \"\"");
  88. return;
  89. }
  90. ConstString param(params[0]);
  91. long index = -1;
  92. for(long i = 0; i < events; i++)
  93. {
  94. if(events[i].name == param)
  95. {
  96. index = i;
  97. break;
  98. }
  99. }
  100. if(index < 0)
  101. {
  102. LogicDebug("Synchronizer -> invalidate input event name: \"%s\"", params[0]);
  103. return;
  104. }
  105. //Активация
  106. static const ConstString evt("event");
  107. if(cid == evt)
  108. {
  109. LogicDebug("Registry event \"%s\"", params[0]);
  110. events[index].state = true;
  111. return;
  112. }
  113. //Деактивация
  114. static const ConstString unevt("unevent");
  115. if(cid == unevt)
  116. {
  117. LogicDebug("Unevent \"%s\"", params[0]);
  118. events[index].state = false;
  119. return;
  120. }
  121. LogicDebugError("Unknown command: %s", id);
  122. }
  123. //Активировать
  124. void Synchronizer::Activate(bool isActive)
  125. {
  126. MissionObject::Activate(isActive);
  127. if(IsActive())
  128. {
  129. LogicDebug("Activate");
  130. }else{
  131. LogicDebug("Deactivate");
  132. }
  133. }
  134. //Инициализировать объект
  135. bool Synchronizer::EditMode_Create(MOPReader & reader)
  136. {
  137. return true;
  138. }
  139. //Обновить параметры
  140. bool Synchronizer::EditMode_Update(MOPReader & reader)
  141. {
  142. return true;
  143. }
  144. //Получить размеры описывающего ящика
  145. void Synchronizer::EditMode_GetSelectBox(Vector & min, Vector & max)
  146. {
  147. min = max = 0.0f;
  148. }
  149. void _cdecl Synchronizer::LogicAll()
  150. {
  151. for(long i = 0; i < events; i++)
  152. {
  153. if(events[i].state)
  154. {
  155. LogicDebug("Activate event \"%s\"", events[i].name.c_str());
  156. events[i].event.Activate(Mission(), false);
  157. events[i].state = false;
  158. }
  159. }
  160. }
  161. void _cdecl Synchronizer::LogicRand()
  162. {
  163. long count = 0;
  164. for(long i = 0; i < events; i++)
  165. {
  166. if(events[i].state)
  167. {
  168. count++;
  169. }
  170. }
  171. if(!count) return;
  172. long index = (long)Rnd(count + 0.999f);
  173. if(index >= count) index = count - 1;
  174. count = 0;
  175. for(long i = 0; i < events; i++)
  176. {
  177. if(events[i].state)
  178. {
  179. if(count++ == index)
  180. {
  181. LogicDebug("Activate event \"%s\"", events[i].name.c_str());
  182. events[i].event.Activate(Mission(), false);
  183. events[i].state = false;
  184. return;
  185. }
  186. }
  187. }
  188. Assert(false);
  189. }
  190. void _cdecl Synchronizer::LogicFirst()
  191. {
  192. for(long i = 0; i < events; i++)
  193. {
  194. if(events[i].state)
  195. {
  196. LogicDebug("Activate event \"%s\"", events[i].name.c_str());
  197. events[i].event.Activate(Mission(), false);
  198. events[i].state = false;
  199. break;
  200. }
  201. }
  202. }
  203. //============================================================================================
  204. //Описание
  205. //============================================================================================
  206. const char * Synchronizer::desc =
  207. "Trigger type:\n"
  208. " #b\"All at one time\"@b when get tick event, all active input triggers,\n"
  209. " sended events and reset it active state\n"
  210. " #b\"One at one time (random)\"@b when get tick event, one random active input trigger\n"
  211. " sended event and reset his active state\n"
  212. " #b\"One at one time (first)\"@b when get tick event, one first active input trigger\n"
  213. " sended event and reset his active state\n"
  214. " ";
  215. const char * Synchronizer::comment =
  216. "Object for synchinize events in time\n"
  217. " \n"
  218. "Commands list:\n"
  219. "----------------------------------------\n"
  220. " Tick event - time for action\n"
  221. "----------------------------------------\n"
  222. " command: tick\n"
  223. " \n"
  224. "----------------------------------------\n"
  225. " Activate input trigger\n"
  226. "----------------------------------------\n"
  227. " command: event\n"
  228. " parm: input trigger name\n"
  229. " \n"
  230. "----------------------------------------\n"
  231. " Deactivate input trigger\n"
  232. "----------------------------------------\n"
  233. " command: unevent\n"
  234. " parm: input trigger name\n"
  235. " \n"
  236. "----------------------------------------\n"
  237. " Reset all input triggers and\n"
  238. " output trigger\n"
  239. "----------------------------------------\n"
  240. " command: reset\n"
  241. " \n"
  242. " ";
  243. //============================================================================================
  244. //Параметры инициализации
  245. //============================================================================================
  246. MOP_BEGINLISTCG(Synchronizer, "Synchronizer", '1.00', 0x0fffffff, Synchronizer::comment, "Logic")
  247. MOP_ENUMBEG("SynchroFunction")
  248. for(dword i = 0; i < ARRSIZE(Synchronizer::logics); i++)
  249. {
  250. MOP_ENUMELEMENT(Synchronizer::logics[i].name.c_str())
  251. }
  252. MOP_ENUMEND
  253. MOP_ENUMC("SynchroFunction", "Type", Synchronizer::desc)
  254. MOP_ARRAYBEGC("Events", 1, 1000, "Synchronize/unsynchronize events")
  255. MOP_STRINGC("Name", "", "Input event name")
  256. MOP_MISSIONTRIGGER("")
  257. MOP_ARRAYEND
  258. MOP_MISSIONTRIGGERG("Tick event", "Tick event")
  259. MOP_BOOLC("Active", true, "Active trigger in start mission time")
  260. MOP_ENDLIST(Synchronizer)