TriggerEventsDlg.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. /*
  2. FinalSun/FinalAlert 2 Mission Editor
  3. Copyright (C) 1999-2024 Electronic Arts, Inc.
  4. Authored by Matthias Wagner
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. */
  16. // TriggerEventsDlg.cpp: Implementierungsdatei
  17. //
  18. #include "stdafx.h"
  19. #include "finalsun.h"
  20. #include "TriggerEventsDlg.h"
  21. #include "mapdata.h"
  22. #include "variables.h"
  23. #include "functions.h"
  24. #include "inlines.h"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. /////////////////////////////////////////////////////////////////////////////
  31. // Dialogfeld CTriggerEventsDlg
  32. CTriggerEventsDlg::CTriggerEventsDlg(CWnd* pParent /*=NULL*/)
  33. : CDialog(CTriggerEventsDlg::IDD, pParent)
  34. {
  35. //{{AFX_DATA_INIT(CTriggerEventsDlg)
  36. // HINWEIS: Der Klassen-Assistent fügt hier Elementinitialisierung ein
  37. //}}AFX_DATA_INIT
  38. }
  39. void CTriggerEventsDlg::DoDataExchange(CDataExchange* pDX)
  40. {
  41. CDialog::DoDataExchange(pDX);
  42. //{{AFX_DATA_MAP(CTriggerEventsDlg)
  43. DDX_Control(pDX, IDC_PARAMVALUE, m_ParamValue);
  44. DDX_Control(pDX, IDC_PARAMETER, m_Parameter);
  45. DDX_Control(pDX, IDC_EVENTTYPE, m_EventType);
  46. DDX_Control(pDX, IDC_EVENTDESCRIPTION, m_EventDescription);
  47. DDX_Control(pDX, IDC_EVENT, m_Event);
  48. //}}AFX_DATA_MAP
  49. }
  50. BEGIN_MESSAGE_MAP(CTriggerEventsDlg, CDialog)
  51. //{{AFX_MSG_MAP(CTriggerEventsDlg)
  52. ON_BN_CLICKED(IDC_NEWEVENT, OnNewevent)
  53. ON_BN_CLICKED(IDC_DELETEEVENT, OnDeleteevent)
  54. ON_CBN_SELCHANGE(IDC_EVENT, OnSelchangeEvent)
  55. ON_CBN_EDITCHANGE(IDC_EVENTTYPE, OnEditchangeEventtype)
  56. ON_LBN_SELCHANGE(IDC_PARAMETER, OnSelchangeParameter)
  57. ON_CBN_EDITCHANGE(IDC_PARAMVALUE, OnEditchangeParamvalue)
  58. //}}AFX_MSG_MAP
  59. END_MESSAGE_MAP()
  60. /////////////////////////////////////////////////////////////////////////////
  61. // Behandlungsroutinen für Nachrichten CTriggerEventsDlg
  62. // MW 07/23/01: Added this because startpos=1+curev*3 isn´t anymore valid for calculating the next event
  63. int GetEventParamStart(CString& EventData, int param)
  64. {
  65. int count=atoi(GetParam(EventData, 0));
  66. if(param>=count) return -1;
  67. int pos=1;
  68. int i;
  69. for(i=0;i<param;i++)
  70. {
  71. pos+=1; // jump to first eventtype param
  72. int needs=atoi(GetParam(EventData, pos));
  73. pos+=2; // jump to next usual eventtype
  74. if(needs==2) // if needs of last eventtype is 2, we need to add 1
  75. {
  76. pos+=1;
  77. }
  78. }
  79. return pos;
  80. }
  81. void CTriggerEventsDlg::OnNewevent()
  82. {
  83. CIniFile& ini=Map->GetIniFile();
  84. if(m_currentTrigger.GetLength()==0) return;
  85. CIniFileSection& sec=ini.sections["Events"];
  86. int cval=atoi(GetParam(sec.values[(LPCTSTR)m_currentTrigger],0));
  87. cval++;
  88. char c[50];
  89. itoa(cval,c,10);
  90. sec.values[(LPCTSTR)m_currentTrigger]=SetParam(sec.values[(LPCTSTR)m_currentTrigger],0,c);
  91. sec.values[(LPCTSTR)m_currentTrigger]+=",0,0,0";
  92. UpdateDialog();
  93. m_Event.SetCurSel(cval-1);
  94. OnSelchangeEvent();
  95. }
  96. int FindTokenX(CString data, char token, int n)
  97. {
  98. if(n<=0) return -1;
  99. int found=0;
  100. int pos=0;
  101. while(found<n)
  102. {
  103. if(!pos)
  104. pos=data.Find(token, 0);
  105. else
  106. pos=data.Find(token, pos+1);
  107. if(pos<0)
  108. {
  109. return -1;
  110. }
  111. found++;
  112. }
  113. return pos;
  114. }
  115. void CTriggerEventsDlg::OnDeleteevent()
  116. {
  117. char d[50];
  118. //itoa(FindTokenX("0,1,2,3,4", ',', 3),d,10);
  119. //MessageBox(d);
  120. CIniFile& ini=Map->GetIniFile();
  121. if(m_currentTrigger.GetLength()==0) return;
  122. int sel2=m_Event.GetCurSel();
  123. if(sel2<0) return;
  124. int curev=m_Event.GetItemData(sel2);
  125. if(MessageBox("Do you really want to delete this event?","Delete event", MB_YESNO)==IDNO) return;
  126. CIniFileSection& sec=ini.sections["Events"];
  127. CString data;
  128. data=sec.values[(LPCTSTR)m_currentTrigger];
  129. CString orig_data=data;
  130. int v=atoi(GetParam(data,0));
  131. char c[50];
  132. v--;
  133. itoa(v,c,10);
  134. data=SetParam(data,0, c);
  135. int pos=GetEventParamStart(orig_data, curev);//1+curev*3;
  136. //int posc=GetEventParamStart(orig_data, v);//1+v*3;
  137. // MW 07/23/01:
  138. // NEW DELETE EVENT CODE...
  139. // Now check for those 2 param + code events...
  140. BOOL bEvent1Needs4=FALSE;
  141. if(GetParam(data, pos+1)=="2") bEvent1Needs4=TRUE;
  142. int count=3;
  143. if(bEvent1Needs4) count=4;
  144. int del_start=FindTokenX(data, ',', pos);
  145. int del_end=FindTokenX(data, ',', pos+count);
  146. if(del_end<0)
  147. {
  148. // beyond end, so delete all...
  149. del_end=data.GetLength();
  150. }
  151. data.Delete(del_start, del_end-del_start);
  152. /*
  153. old delete event code, that used replacement. Not possible anymore because of 4 values/event sometimes now
  154. int i;
  155. for(i=0;i<3;i++)
  156. data=SetParam(data,pos+i, GetParam(data,posc+i));
  157. char* cupos=(char*)(LPCTSTR)data;
  158. for(i=0;i<posc;i++)
  159. {
  160. cupos=strchr(cupos+1, ',');
  161. if(i==posc-1)
  162. {
  163. cupos[0]=0;
  164. break;
  165. }
  166. }*/
  167. sec.values[(LPCTSTR)m_currentTrigger]=data;
  168. UpdateDialog();
  169. }
  170. void CTriggerEventsDlg::OnSelchangeEvent()
  171. {
  172. CIniFile& ini=Map->GetIniFile();
  173. if(m_currentTrigger.GetLength()==0) return;
  174. int selev=m_Event.GetCurSel();
  175. if(selev<0) return;
  176. int curev=m_Event.GetItemData(selev);
  177. int i;
  178. CString EventData;
  179. EventData=ini.sections["Events"].values[(LPCTSTR)m_currentTrigger];
  180. int startpos=GetEventParamStart(EventData, curev); //1+curev*3;
  181. CString EventType=GetParam(EventData,startpos);
  182. m_EventType.SetWindowText(EventType);
  183. for(i=0;i<m_EventType.GetCount();i++)
  184. {
  185. CString tmp;
  186. m_EventType.GetLBText(i,tmp);
  187. TruncSpace(tmp);
  188. if(tmp==EventType)
  189. m_EventType.SetCurSel(i);
  190. }
  191. OnEditchangeEventtype();
  192. }
  193. void CTriggerEventsDlg::OnEditchangeEventtype()
  194. {
  195. CIniFile& ini=Map->GetIniFile();
  196. if(m_currentTrigger.GetLength()==0) return;
  197. int selev=m_Event.GetCurSel();
  198. if(selev<0) return;
  199. int curev=m_Event.GetItemData(selev);
  200. CString e1,e2;
  201. while(m_Parameter.DeleteString(0)!=CB_ERR);
  202. CString eventtype,eventdata;
  203. m_EventType.GetWindowText(eventtype);
  204. TruncSpace(eventtype);
  205. if(eventtype.GetLength()==0)
  206. {
  207. eventtype="0";
  208. m_EventType.SetWindowText(eventtype);
  209. }
  210. int pos=GetEventParamStart(ini.sections["Events"].values[(LPCTSTR)m_currentTrigger], curev); //1+3*curev;
  211. BOOL bAlready4=FALSE;
  212. if(atoi(GetParam(ini.sections["Events"].values[(LPCTSTR)m_currentTrigger], pos+1))==2)
  213. bAlready4=TRUE;
  214. ini.sections["Events"].values[(LPCTSTR)m_currentTrigger]=SetParam(ini.sections["Events"].values[(LPCTSTR)m_currentTrigger], pos, (LPCTSTR)eventtype);
  215. CString evsec="Events";
  216. #ifdef RA2_MODE
  217. evsec="EventsRA2";
  218. #endif
  219. if(g_data.sections[evsec].FindName(eventtype)<0) return;
  220. eventdata=g_data.sections[evsec].values[eventtype];
  221. #ifdef RA2_MODE
  222. if(g_data.sections["EventsRA2"].FindName(eventtype)>=0)
  223. eventdata=g_data.sections["EventsRA2"].values[eventtype];
  224. #endif
  225. CString desc=GetParam(eventdata,5);
  226. desc.Replace("%1",",");
  227. m_EventDescription.SetWindowText(desc);
  228. CString ptype[2];
  229. ptype[0]=GetParam(eventdata,1);
  230. ptype[1]=GetParam(eventdata,2);
  231. int pListType[2];
  232. pListType[0]=atoi(GetParam(g_data.sections["ParamTypes"].values[ptype[0]], 1));
  233. pListType[1]=atoi(GetParam(g_data.sections["ParamTypes"].values[ptype[1]], 1));
  234. int code=atoi(GetParam(g_data.sections["ParamTypes"].values[ptype[0]], 2)); // usually 0
  235. // **************************************
  236. // MW ADD SUPPORT FOR 2 PARAMS+CODE
  237. if(code==2)
  238. {
  239. // add code + event 0 ONLY IF THEY DO NOT ALREADY EXIST
  240. if(!bAlready4) ini.sections["Events"].values[(LPCTSTR)m_currentTrigger]=SetParam(ini.sections["Events"].values[(LPCTSTR)m_currentTrigger], pos+1, "2,0");
  241. }
  242. else
  243. {
  244. // remove code + event 0
  245. char c[50];
  246. itoa(code, c, 10);
  247. ini.sections["Events"].values[(LPCTSTR)m_currentTrigger]=SetParam(ini.sections["Events"].values[(LPCTSTR)m_currentTrigger], pos+1, c);
  248. if(bAlready4)
  249. {
  250. CString& data=ini.sections["Events"].values[(LPCTSTR)m_currentTrigger];
  251. int del_start=FindTokenX(data, ',', pos+2);
  252. int del_end=FindTokenX(data, ',', pos+3);
  253. if(del_end<0)
  254. {
  255. // beyond end, so delete all...
  256. del_end=data.GetLength();
  257. }
  258. data.Delete(del_start, del_end-del_start);
  259. }
  260. }
  261. // **************************************
  262. int i;
  263. for(i=0;i<2;i++)
  264. {
  265. int add=0;
  266. if(code==2) add=1;
  267. if(atoi(ptype[i])!=0 && atoi(ptype[i])>0 && atoi(ptype[i])!=47)
  268. {
  269. CString paramname=GetParam(g_data.sections["ParamTypes"].values[ptype[i]], 0);
  270. m_Parameter.SetItemData(m_Parameter.AddString(paramname), i+add);
  271. }
  272. }
  273. m_ParamValue.SetWindowText("");
  274. if(m_Parameter.GetCount()>0) {
  275. m_Parameter.SetCurSel(0);
  276. OnSelchangeParameter();
  277. }
  278. RepairTrigger(ini.sections["Triggers"].values[m_currentTrigger]);
  279. }
  280. void CTriggerEventsDlg::OnSelchangeParameter()
  281. {
  282. CIniFile& ini=Map->GetIniFile();
  283. if(m_currentTrigger.GetLength()==0) return;
  284. int selev=m_Event.GetCurSel();
  285. if(selev<0) return;
  286. int curev=m_Event.GetItemData(selev);
  287. int curselparam=m_Parameter.GetCurSel();
  288. if(curselparam<0)
  289. {
  290. m_ParamValue.SetWindowText("");
  291. return;
  292. }
  293. int curparam=m_Parameter.GetItemData(curselparam);
  294. CString EventData;
  295. EventData=ini.sections["Events"].values[(LPCTSTR)m_currentTrigger];
  296. int startpos=GetEventParamStart(EventData, curev);//1+curev*3;
  297. // MW FIX FOR CODE!=0
  298. int original_cuparam=curparam;
  299. #ifdef RA2_MODE
  300. CString Param1=GetParam(g_data.sections["EventsRA2"].values[GetParam(EventData,startpos)],1);
  301. CString Code=GetParam(g_data.sections["ParamTypes"].values[Param1],2);
  302. //MessageBox(Param1, Code);
  303. if(atoi(Code)!=0) curparam--;
  304. #endif
  305. // END FIx
  306. CString ParamType=GetParam(g_data.sections["Events"].values[GetParam(EventData,startpos)],1+curparam);
  307. #ifdef RA2_MODE
  308. if(g_data.sections["EventsRA2"].FindName(GetParam(EventData, startpos))>=0) ParamType=GetParam(g_data.sections["EventsRA2"].values[GetParam(EventData,startpos)],1+curparam);
  309. #endif
  310. if(atoi(ParamType)<0)
  311. {
  312. }
  313. else
  314. {
  315. CString ListType=GetParam(g_data.sections["ParamTypes"].values[ParamType],1);
  316. HandleParamList(m_ParamValue, atoi(ListType));
  317. m_ParamValue.SetWindowText(GetParam(EventData,startpos+1+original_cuparam));
  318. int i;
  319. BOOL bFound=FALSE;
  320. for(i=0;i<m_ParamValue.GetCount();i++)
  321. {
  322. CString tmp;
  323. m_ParamValue.GetLBText(i,tmp);
  324. TruncSpace(tmp);
  325. if(tmp==GetParam(EventData,startpos+1+original_cuparam))
  326. {
  327. m_ParamValue.SetCurSel(i);
  328. bFound=TRUE;
  329. break;
  330. }
  331. }
  332. /*if(!bFound)
  333. {
  334. // not found, change it...
  335. if(m_ParamValue.GetCount()) {
  336. m_ParamValue.SetCurSel(0);
  337. OnEditchangeParamvalue();
  338. }
  339. else
  340. {
  341. // not numeric value?
  342. CString p=GetParam(EventData,startpos+1+original_cuparam);
  343. char c[50];
  344. itoa(atoi(p), c, 10);
  345. if(c!=p) {
  346. m_ParamValue.SetWindowText("0");
  347. OnEditchangeParamvalue();
  348. }
  349. }
  350. }*/
  351. }
  352. }
  353. void CTriggerEventsDlg::OnEditchangeParamvalue()
  354. {
  355. CIniFile& ini=Map->GetIniFile();
  356. if(m_currentTrigger.GetLength()==0) return;
  357. int selev=m_Event.GetCurSel();
  358. if(selev<0) return;
  359. int curev=m_Event.GetItemData(selev);
  360. int curselparam=m_Parameter.GetCurSel();
  361. if(curselparam<0)
  362. {
  363. m_ParamValue.SetWindowText("");
  364. return;
  365. }
  366. int curparam=m_Parameter.GetItemData(curselparam);
  367. CString EventData;
  368. EventData=ini.sections["Events"].values[(LPCTSTR)m_currentTrigger];
  369. int startpos=GetEventParamStart(EventData, curev);// 1+curev*3;
  370. CString newVal;
  371. m_ParamValue.GetWindowText(newVal);
  372. TruncSpace(newVal);
  373. newVal.TrimLeft();
  374. if(newVal.Find(",",0)>=0) newVal.SetAt(newVal.Find(",",0), 0);
  375. ini.sections["Events"].values[(LPCTSTR)m_currentTrigger]=SetParam(EventData, startpos+1+curparam, newVal);
  376. }
  377. void CTriggerEventsDlg::UpdateDialog()
  378. {
  379. // MW 07/20/01
  380. Clear();
  381. if(m_currentTrigger.GetLength()==0)
  382. {
  383. while(m_Event.DeleteString(0)!=CB_ERR);
  384. return;
  385. }
  386. CIniFile& ini=Map->GetIniFile();
  387. while(m_EventType.DeleteString(0)!=CB_ERR);
  388. int i;
  389. //9.3.2001: Only use specified section, do not merge
  390. #ifndef RA2_MODE
  391. CString sec="Events";
  392. #else
  393. CString sec="EventsRA2";
  394. #endif
  395. for(i=0;i<g_data.sections[sec].values.size();i++)
  396. {
  397. CString eventid = *g_data.sections[sec].GetValueName(i); //GetParam(*g_data.sections["Events"].GetValue(i),8);
  398. CString eventdata=*g_data.sections[sec].GetValue(i);
  399. /*#ifdef RA2_MODE
  400. if(g_data.sections["EventsRA2"].FindName(eventid)>=0)
  401. eventdata=g_data.sections["EventsRA2"].values[eventid];
  402. #endif*/
  403. CString text=eventid+" "+GetParam(eventdata,0);
  404. text.Replace("%1",",");
  405. #ifdef RA2_MODE
  406. // MW 07/18/01
  407. // for yuri mode, only check if it´s for RA2, else support it only if YR isnt´needed...
  408. if(GetParam(eventdata, 7)=="1" && ( yuri_mode || !atoi(GetParam(eventdata,9)) ) )
  409. {
  410. #else
  411. if(GetParam(eventdata, 6)=="1")
  412. {
  413. #endif
  414. m_EventType.AddString(text);
  415. }
  416. }
  417. int cur_sel=m_Event.GetCurSel();
  418. while(m_Event.DeleteString(0)!=CB_ERR);
  419. CString Data=ini.sections["Events"].values[m_currentTrigger];
  420. int count=atoi(GetParam(Data,0));
  421. for(i=0;i<count;i++)
  422. {
  423. char c[50];
  424. itoa(i,c,10);
  425. CString s=TranslateStringACP("Event");
  426. s+=" ";
  427. s+=c;
  428. m_Event.SetItemData(m_Event.AddString(s), i);
  429. }
  430. if(cur_sel<0) cur_sel=0;
  431. if(cur_sel>=count) cur_sel=count-1;
  432. m_Event.SetCurSel(cur_sel);
  433. OnSelchangeEvent();
  434. }
  435. // MW 07/20/01
  436. void CTriggerEventsDlg::Clear()
  437. {
  438. m_EventType.SetWindowText("");
  439. while(m_Parameter.DeleteString(0)!=LB_ERR);
  440. m_ParamValue.SetWindowText("");
  441. m_EventDescription.SetWindowText("");
  442. }