BaseGUITable.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. #include "BaseGUITable.h"
  2. #include "GUIWidget.h"
  3. BaseGUITable::Element::Element()
  4. {
  5. widget.name = null;
  6. widget.p = null;
  7. number.name = null;
  8. number.p = null;
  9. title.name = null;
  10. title.p = null;
  11. delay = 0.0f;
  12. rel = false;
  13. play = false;
  14. }
  15. BaseGUITable:: BaseGUITable() : elems(_FL_)
  16. {
  17. tickSound = null;
  18. sound = null; fadeOut = 0.0f;
  19. }
  20. BaseGUITable::~BaseGUITable()
  21. {
  22. if( EditMode_IsOn())
  23. return;
  24. for( int i = 0 ; i < elems ; i++ )
  25. {
  26. Element &e = elems[i];
  27. RELEASE(e.number.p)
  28. }
  29. RELEASE(sound);
  30. RELEASE(tickSound);
  31. }
  32. void BaseGUITable::Restart()
  33. {
  34. //
  35. }
  36. bool BaseGUITable::Create (MOPReader &reader)
  37. {
  38. InitParams(reader);
  39. return true;
  40. }
  41. bool BaseGUITable::EditMode_Update(MOPReader &reader)
  42. {
  43. InitParams(reader);
  44. return true;
  45. }
  46. void BaseGUITable::Show(bool isShow)
  47. {
  48. if(!IsShow())
  49. {
  50. if( isShow )
  51. {
  52. const char *diff_name = "Profile.Global.Difficulty";
  53. ICoreStorageString *d = api->Storage().GetItemString(diff_name,_FL_);
  54. if( d && d->IsValidate())
  55. {
  56. const char *diff = d->Get();
  57. if( string::NotEmpty(diff))
  58. {
  59. SetTable(diff);
  60. RELEASE(d)
  61. SetUpdate(&BaseGUITable::Update,ML_GUI1);
  62. }
  63. else
  64. {
  65. LogicDebugError("Invalid game difficulty value.");
  66. RELEASE(d) return;
  67. }
  68. }
  69. else
  70. {
  71. LogicDebugError("Base variable \"%s\" not found.",diff_name);
  72. RELEASE(d) return;
  73. }
  74. }
  75. }
  76. else
  77. {
  78. if(!isShow )
  79. DelUpdate(&BaseGUITable::Update);
  80. }
  81. MissionObject::Show(isShow);
  82. }
  83. void BaseGUITable::SetTable(const char *diff)
  84. {
  85. index = 0; time = 0.0f; wait = false; skip = false;
  86. ICoreStorageFloat *r;
  87. for( int i = 0 ; i < elems ; i++ )
  88. {
  89. Element &e = elems[i];
  90. RELEASE(e.number.p)
  91. char buf[128]; const char *name;
  92. if( string::NotEmpty(e.number.name))
  93. {
  94. if( e.rel ) // смотрим переменную в разделе текущей сложности
  95. {
  96. sprintf_s(buf,sizeof(buf),"Profile.%s.%s",diff,e.number.name);
  97. name = buf;
  98. }
  99. else // абсолютный путь до переменной
  100. {
  101. name = e.number.name;
  102. }
  103. r = api->Storage().GetItemFloat(name,_FL_);
  104. if( r && r->IsValidate())
  105. {
  106. e.number.p = r;
  107. }
  108. else
  109. {
  110. LogicDebugError("Base variable \"%s\" not found.",name);
  111. e.number.p = null;
  112. RELEASE(r)
  113. }
  114. }
  115. else
  116. {
  117. LogicDebugError("Elements[%d].Number is empty.",i);
  118. e.number.p = null;
  119. }
  120. }
  121. }
  122. void _cdecl BaseGUITable::Update(float dltTime, long level)
  123. {
  124. do
  125. {
  126. if( index < elems )
  127. {
  128. if( skip == false )
  129. {
  130. if( Controls().GetControlStateType(menu) == CST_ACTIVATED )
  131. skip = true;
  132. }
  133. const Element &e = elems[index];
  134. if( wait )
  135. {
  136. // if( Controls().GetControlStateType(menu) == CST_ACTIVATED )
  137. // e.widget.p->Activate(true);
  138. tickPeriodicTime -= dltTime;
  139. if (tickSoundName.NotEmpty() && tickPeriodic && tickPeriodicTime<=0.0f)
  140. {
  141. tickPeriodicTime += tickCooldown;
  142. Sound().Create(tickSoundName.c_str(), _FL_, true, true);
  143. }
  144. if( skip )
  145. e.widget.p->Activate(true);
  146. if( skip || e.widget.p->Complete())
  147. {
  148. if( sound )
  149. sound->FadeOut(fadeOut);
  150. if (tickSound && !tickPeriodic)
  151. tickSound->FadeOut(fadeOut);
  152. if (tickEndSoundName.NotEmpty())
  153. Sound().Create(tickEndSoundName.c_str(), _FL_, true, true);
  154. index++; time = 0.0f;
  155. wait = false;
  156. if( index >= elems )
  157. {
  158. complete.Activate(Mission(),false);
  159. }
  160. }
  161. }
  162. else
  163. {
  164. if( e.widget.p &&
  165. e.number.p )
  166. {
  167. if( skip == false )
  168. time += dltTime;
  169. if( skip || time >= e.delay )
  170. {
  171. if( e.title.p )
  172. e.title.p->Show(true);
  173. e.widget.p->Activate(e.play); // разрешаем/запрещаем анимацию набора значения
  174. int val = (int)e.number.p->Get();
  175. static char buf[32];
  176. sprintf_s(buf,sizeof(buf),"%d",val);
  177. const char *s = buf;
  178. e.widget.p->Command("SetString",1,&s);
  179. if( sound && e.play )
  180. {
  181. sound->Stop();
  182. sound->Play();
  183. }
  184. tickPeriodicTime = tickCooldown;
  185. if (tickSoundName.NotEmpty() && !tickPeriodic && e.play)
  186. {
  187. if (!tickSound)
  188. tickSound = Sound().Create(tickSoundName.c_str(), _FL_, false, false);
  189. if (tickSound && e.play)
  190. {
  191. tickSound->Stop();
  192. tickSound->Play();
  193. }
  194. }
  195. wait = true;
  196. }
  197. }
  198. else
  199. {
  200. index++;
  201. if( index >= elems )
  202. {
  203. complete.Activate(Mission(),false);
  204. }
  205. }
  206. }
  207. }
  208. else
  209. {
  210. Show(false);
  211. }
  212. }
  213. while( skip && IsShow());
  214. }
  215. void BaseGUITable::PostCreate()
  216. {
  217. menu = Controls().FindControlByName(menu_control);
  218. MOSafePointer p; MissionObject *q;
  219. for( int i = 0 ; i < elems ; i++ )
  220. {
  221. Element &e = elems[i];
  222. if( string::NotEmpty(e.widget.name))
  223. {
  224. FindObject(ConstString(e.widget.name),p); q = p.Ptr();
  225. if( q && q->Is(InterfaceUtils::GetWidgetId()))
  226. {
  227. e.widget.p = (GUIWidget *)q;
  228. }
  229. else
  230. {
  231. LogicDebugError("GUIWidget \"%s\" not found.",e.widget.name);
  232. e.widget.p = null;
  233. }
  234. }
  235. else
  236. {
  237. LogicDebugError("Elements[%d].Widget is empty.",i);
  238. e.widget.p = null;
  239. }
  240. if( string::NotEmpty(e.title.name))
  241. {
  242. FindObject(ConstString(e.title.name),p); q = p.Ptr();
  243. if( q )
  244. {
  245. e.title.p = q;
  246. }
  247. else
  248. {
  249. LogicDebugError("MissionObject \"%s\" not found.",e.title.name);
  250. e.title.p = null;
  251. }
  252. }
  253. else
  254. e.title.p = null;
  255. }
  256. Show(show);
  257. }
  258. void BaseGUITable::InitParams(MOPReader &reader)
  259. {
  260. const char *name = reader.String().c_str();
  261. RELEASE(tickSound);
  262. if( !sound || !string::IsEqual(sound->GetName(),name))
  263. {
  264. RELEASE(sound)
  265. if( string::NotEmpty(name))
  266. {
  267. sound = Sound().Create(name,_FL_,false,false);
  268. }
  269. }
  270. fadeOut = reader.Float();
  271. tickSoundName = reader.String();
  272. tickPeriodic = reader.Bool();
  273. tickCooldown = reader.Float();
  274. tickEndSoundName = reader.String();
  275. long count = reader.Array();
  276. elems.DelAll();
  277. elems.Reserve(count);
  278. for( int i = 0 ; i < count ; i++ )
  279. {
  280. Element &e = elems[elems.Add()];
  281. e.widget.name = reader.String().c_str();
  282. e.number.name = reader.String().c_str();
  283. e.rel = reader.Bool();
  284. e.delay = reader.Float();
  285. e.title.name = reader.String().c_str();
  286. e.play = reader.Bool();
  287. }
  288. menu_control = reader.String().c_str();
  289. complete.Init(reader);
  290. show = reader.Bool();
  291. MissionObject::Show(false);
  292. tickPeriodicTime = tickCooldown;
  293. }
  294. void BaseGUITable::Command(const char *id, dword numParams, const char **params)
  295. {
  296. if( string::IsEmpty(id))
  297. return;
  298. if( EditMode_IsOn())
  299. return;
  300. if( string::IsEqual(id,"Clear"))
  301. {
  302. const char *s = "";
  303. for( int i = 0 ; i < elems ; i++ )
  304. {
  305. const Element &e = elems[i];
  306. if( e.widget.p )
  307. {
  308. e.widget.p->Activate(false);
  309. e.widget.p->Command("SetString",1,&s);
  310. }
  311. if( e.title.p )
  312. e.title.p->Show(false);
  313. }
  314. LogicDebug("Command <Clear>: done");
  315. }
  316. else
  317. {
  318. LogicDebugError("Invalid command name: \"%s\"",id);
  319. }
  320. }
  321. static const char *_desc =
  322. "GUI Table\n\n"
  323. " Use to display game statistics\n\n"
  324. "Commands:\n\n"
  325. " Clear - clear all items (prepare for next show)";
  326. MOP_BEGINLISTCG(BaseGUITable, "GUI Table", '1.00', 2000, _desc, "Interface")
  327. MOP_STRINGC("Sound", "", "Звук набора значения")
  328. MOP_FLOATEXC("Fade out", 0.0f, 0.0f, 2.0f, "Время затухания")
  329. MOP_GROUPBEG("Tick sound group")
  330. MOP_STRINGC("Tick sound", "", "Звук набора значения")
  331. MOP_BOOLC("Tick periodic", true, "Если true, то звук перезапускается каждые Tick time секунд")
  332. MOP_FLOATC("Tick time", 1.0f, "Время между стартом звука")
  333. MOP_STRINGC("Tick end sound", "", "Звук окончания набора значения")
  334. MOP_GROUPEND()
  335. MOP_ARRAYBEG("Elements", 0, 100)
  336. MOP_STRINGC("Widget", "", "Виджет для отображения значения переменной")
  337. MOP_STRINGC("Number", "", "Имя переменной из базы игры")
  338. MOP_BOOLC("Relative", true, "Добавлять к имени переменной префикс [Profile.<уровень сложности>.]")
  339. MOP_FLOATEXC("Delay", 0.5f, 0.0f, 5.0f, "Задержка перед активацией элемента")
  340. MOP_STRINGC("Title", "", "Объект, появляющийся при активации элемента")
  341. MOP_BOOLC("Play", true, "Отыгрывать анимацию набора значения")
  342. MOP_ARRAYEND
  343. MOP_STRINGC("Skip", "Menu_Select", "Имя контрола для скипания анимации таблицы")
  344. MOP_MISSIONTRIGGERC("Complete","")
  345. MOP_BOOLC("Show", false, "Запускать таблицу автоматически при старте миссии")
  346. MOP_ENDLIST(BaseGUITable)