/* FinalSun/FinalAlert 2 Mission Editor Copyright (C) 1999-2024 Electronic Arts, Inc. Authored by Matthias Wagner This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ // TriggerEventsDlg.cpp: Implementierungsdatei // #include "stdafx.h" #include "finalsun.h" #include "TriggerEventsDlg.h" #include "mapdata.h" #include "variables.h" #include "functions.h" #include "inlines.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // Dialogfeld CTriggerEventsDlg CTriggerEventsDlg::CTriggerEventsDlg(CWnd* pParent /*=NULL*/) : CDialog(CTriggerEventsDlg::IDD, pParent) { //{{AFX_DATA_INIT(CTriggerEventsDlg) // HINWEIS: Der Klassen-Assistent fügt hier Elementinitialisierung ein //}}AFX_DATA_INIT } void CTriggerEventsDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTriggerEventsDlg) DDX_Control(pDX, IDC_PARAMVALUE, m_ParamValue); DDX_Control(pDX, IDC_PARAMETER, m_Parameter); DDX_Control(pDX, IDC_EVENTTYPE, m_EventType); DDX_Control(pDX, IDC_EVENTDESCRIPTION, m_EventDescription); DDX_Control(pDX, IDC_EVENT, m_Event); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CTriggerEventsDlg, CDialog) //{{AFX_MSG_MAP(CTriggerEventsDlg) ON_BN_CLICKED(IDC_NEWEVENT, OnNewevent) ON_BN_CLICKED(IDC_DELETEEVENT, OnDeleteevent) ON_CBN_SELCHANGE(IDC_EVENT, OnSelchangeEvent) ON_CBN_EDITCHANGE(IDC_EVENTTYPE, OnEditchangeEventtype) ON_LBN_SELCHANGE(IDC_PARAMETER, OnSelchangeParameter) ON_CBN_EDITCHANGE(IDC_PARAMVALUE, OnEditchangeParamvalue) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Behandlungsroutinen für Nachrichten CTriggerEventsDlg // MW 07/23/01: Added this because startpos=1+curev*3 isn´t anymore valid for calculating the next event int GetEventParamStart(const CString& EventData, int param) { int count = atoi(GetParam(EventData, 0)); if (param >= count) return -1; int pos = 1; int i; for (i = 0; i < param; i++) { pos += 1; // jump to first eventtype param int needs = atoi(GetParam(EventData, pos)); pos += 2; // jump to next usual eventtype if (needs == 2) // if needs of last eventtype is 2, we need to add 1 { pos += 1; } } return pos; } void CTriggerEventsDlg::OnNewevent() { CIniFile& ini = Map->GetIniFile(); if (m_currentTrigger.GetLength() == 0) { return; } CIniFileSection& sec = ini.AddSection("Events"); int cval = atoi(GetParam(sec.GetString(m_currentTrigger), 0)); cval++; char c[50]; itoa(cval, c, 10); auto&& defParam = SetParam(sec[m_currentTrigger], 0, c) + ",0,0,0"; sec.SetString(m_currentTrigger, std::move(defParam)); UpdateDialog(); m_Event.SetCurSel(cval - 1); OnSelchangeEvent(); } int FindTokenX(CString data, char token, int n) { if (n <= 0) return -1; int found = 0; int pos = 0; while (found < n) { if (!pos) pos = data.Find(token, 0); else pos = data.Find(token, pos + 1); if (pos < 0) { return -1; } found++; } return pos; } void CTriggerEventsDlg::OnDeleteevent() { char d[50]; //itoa(FindTokenX("0,1,2,3,4", ',', 3),d,10); //MessageBox(d); CIniFile& ini = Map->GetIniFile(); if (m_currentTrigger.GetLength() == 0) { return; } int sel2 = m_Event.GetCurSel(); if (sel2 < 0) { return; } int curev = m_Event.GetItemData(sel2); if (MessageBox("Do you really want to delete this event?", "Delete event", MB_YESNO) == IDNO) { return; } auto const& orig_data = ini["Events"][m_currentTrigger]; CString data = orig_data; int v = atoi(GetParam(data, 0)); char c[50]; v--; itoa(v, c, 10); data = SetParam(data, 0, c); int pos = GetEventParamStart(orig_data, curev);//1+curev*3; //int posc=GetEventParamStart(orig_data, v);//1+v*3; // MW 07/23/01: // NEW DELETE EVENT CODE... // Now check for those 2 param + code events... BOOL bEvent1Needs4 = FALSE; if (GetParam(data, pos + 1) == "2") { bEvent1Needs4 = TRUE; } int count = 3; if (bEvent1Needs4) { count = 4; } int del_start = FindTokenX(data, ',', pos); int del_end = FindTokenX(data, ',', pos + count); if (del_end < 0) { // beyond end, so delete all... del_end = data.GetLength(); } data.Delete(del_start, del_end - del_start); /* old delete event code, that used replacement. Not possible anymore because of 4 values/event sometimes now int i; for(i=0;i<3;i++) data=SetParam(data,pos+i, GetParam(data,posc+i)); char* cupos=(char*)(LPCTSTR)data; for(i=0;iGetIniFile(); if (m_currentTrigger.GetLength() == 0) { return; } int selev = m_Event.GetCurSel(); if (selev < 0) { return; } int curev = m_Event.GetItemData(selev); int i; auto const& EventData = ini["Events"][m_currentTrigger]; int startpos = GetEventParamStart(EventData, curev); //1+curev*3; CString EventType = GetParam(EventData, startpos); m_EventType.SetWindowText(EventType); for (i = 0; i < m_EventType.GetCount(); i++) { CString tmp; m_EventType.GetLBText(i, tmp); TruncSpace(tmp); if (tmp == EventType) { m_EventType.SetCurSel(i); } } OnEditchangeEventtype(); } void CTriggerEventsDlg::OnEditchangeEventtype() { CIniFile& ini = Map->GetIniFile(); if (m_currentTrigger.GetLength() == 0) { return; } int selev = m_Event.GetCurSel(); if (selev < 0) { return; } int curev = m_Event.GetItemData(selev); CString e1, e2; while (m_Parameter.DeleteString(0) != CB_ERR); CString eventtype, eventdata; m_EventType.GetWindowText(eventtype); TruncSpace(eventtype); if (eventtype.GetLength() == 0) { eventtype = "0"; m_EventType.SetWindowText(eventtype); } int pos = GetEventParamStart(ini["Events"][m_currentTrigger], curev); //1+3*curev; BOOL bAlready4 = FALSE; if (atoi(GetParam(ini["Events"][m_currentTrigger], pos + 1)) == 2) { bAlready4 = TRUE; } ini.SetString("Events", m_currentTrigger, SetParam(ini["Events"][m_currentTrigger], pos, eventtype)); CString evsec = "Events"; #ifdef RA2_MODE evsec = "EventsRA2"; #endif if (!g_data[evsec].Exists(eventtype)) { return; } eventdata = g_data[evsec][eventtype]; #ifdef RA2_MODE auto const ra2EventConf = g_data.GetString("EventsRA2", eventtype); if (!ra2EventConf.IsEmpty()) { eventdata = ra2EventConf; } #endif CString desc = GetParam(eventdata, 5); desc.Replace("%1", ","); m_EventDescription.SetWindowText(desc); CString ptype[2]; ptype[0] = GetParam(eventdata, 1); ptype[1] = GetParam(eventdata, 2); int pListType[2]; pListType[0] = atoi(GetParam(g_data["ParamTypes"][ptype[0]], 1)); pListType[1] = atoi(GetParam(g_data["ParamTypes"][ptype[1]], 1)); int code = atoi(GetParam(g_data["ParamTypes"][ptype[0]], 2)); // usually 0 // ************************************** // MW ADD SUPPORT FOR 2 PARAMS+CODE if (code == 2) { // add code + event 0 ONLY IF THEY DO NOT ALREADY EXIST if (!bAlready4) { ini.SetString("Events", m_currentTrigger, SetParam(ini["Events"][m_currentTrigger], pos + 1, "2,0")); } } else { // remove code + event 0 char c[50]; itoa(code, c, 10); ini.SetString("Events", m_currentTrigger, SetParam(ini["Events"][m_currentTrigger], pos + 1, c)); if (bAlready4) { CString data = ini["Events"][m_currentTrigger]; int del_start = FindTokenX(data, ',', pos + 2); int del_end = FindTokenX(data, ',', pos + 3); if (del_end < 0) { // beyond end, so delete all... del_end = data.GetLength(); } data.Delete(del_start, del_end - del_start); ini.SetString("Events", m_currentTrigger, data); } } // ************************************** int i; for (i = 0; i < 2; i++) { int add = 0; if (code == 2) { add = 1; } if (atoi(ptype[i]) != 0 && atoi(ptype[i]) > 0 && atoi(ptype[i]) != 47) { CString paramname = GetParam(g_data["ParamTypes"][ptype[i]], 0); m_Parameter.SetItemData(m_Parameter.AddString(paramname), i + add); } } m_ParamValue.SetWindowText(""); if (m_Parameter.GetCount() > 0) { m_Parameter.SetCurSel(0); OnSelchangeParameter(); } auto triggerInfoCopy = ini["Triggers"][m_currentTrigger]; if (RepairTrigger(triggerInfoCopy)) { ini.SetString("Triggers", m_currentTrigger, triggerInfoCopy); } } void CTriggerEventsDlg::OnSelchangeParameter() { CIniFile& ini = Map->GetIniFile(); if (m_currentTrigger.GetLength() == 0) { return; } int selev = m_Event.GetCurSel(); if (selev < 0) { return; } int curev = m_Event.GetItemData(selev); int curselparam = m_Parameter.GetCurSel(); if (curselparam < 0) { m_ParamValue.SetWindowText(""); return; } int curparam = m_Parameter.GetItemData(curselparam); auto const EventData = ini["Events"][m_currentTrigger]; int startpos = GetEventParamStart(EventData, curev);//1+curev*3; // MW FIX FOR CODE!=0 int original_cuparam = curparam; #ifdef RA2_MODE CString Param1 = GetParam(g_data["EventsRA2"][GetParam(EventData, startpos)], 1); CString Code = GetParam(g_data["ParamTypes"][Param1], 2); //MessageBox(Param1, Code); if (atoi(Code) != 0) curparam--; #endif // END FIx CString ParamType = GetParam(g_data["Events"][GetParam(EventData, startpos)], 1 + curparam); #ifdef RA2_MODE if (g_data["EventsRA2"].FindIndex(GetParam(EventData, startpos)) >= 0) { ParamType = GetParam(g_data["EventsRA2"][GetParam(EventData, startpos)], 1 + curparam); } #endif if (atoi(ParamType) < 0) { return; } CString ListType = GetParam(g_data["ParamTypes"][ParamType], 1); HandleParamList(m_ParamValue, atoi(ListType)); m_ParamValue.SetWindowText(GetParam(EventData, startpos + 1 + original_cuparam)); int i; BOOL bFound = FALSE; for (i = 0; i < m_ParamValue.GetCount(); i++) { CString tmp; m_ParamValue.GetLBText(i, tmp); TruncSpace(tmp); if (tmp == GetParam(EventData, startpos + 1 + original_cuparam)) { m_ParamValue.SetCurSel(i); bFound = TRUE; break; } } /*if(!bFound) { // not found, change it... if(m_ParamValue.GetCount()) { m_ParamValue.SetCurSel(0); OnEditchangeParamvalue(); } else { // not numeric value? CString p=GetParam(EventData,startpos+1+original_cuparam); char c[50]; itoa(atoi(p), c, 10); if(c!=p) { m_ParamValue.SetWindowText("0"); OnEditchangeParamvalue(); } } }*/ } void CTriggerEventsDlg::OnEditchangeParamvalue() { CIniFile& ini = Map->GetIniFile(); if (m_currentTrigger.GetLength() == 0) { return; } int selev = m_Event.GetCurSel(); if (selev < 0) { return; } int curev = m_Event.GetItemData(selev); int curselparam = m_Parameter.GetCurSel(); if (curselparam < 0) { m_ParamValue.SetWindowText(""); return; } int curparam = m_Parameter.GetItemData(curselparam); auto const& eventData = ini["Events"][m_currentTrigger]; int startpos = GetEventParamStart(eventData, curev);// 1+curev*3; CString newVal; m_ParamValue.GetWindowText(newVal); TruncSpace(newVal); newVal.TrimLeft(); if (newVal.Find(",", 0) >= 0) { newVal.SetAt(newVal.Find(",", 0), 0); } ini.SetString("Events", m_currentTrigger, SetParam(eventData, startpos + 1 + curparam, newVal)); } void CTriggerEventsDlg::UpdateDialog() { // MW 07/20/01 Clear(); if (m_currentTrigger.GetLength() == 0) { while (m_Event.DeleteString(0) != CB_ERR); return; } CIniFile& ini = Map->GetIniFile(); while (m_EventType.DeleteString(0) != CB_ERR); int i; //9.3.2001: Only use specified section, do not merge #ifndef RA2_MODE CString sec = "Events"; #else CString sec = "EventsRA2"; #endif for (auto const& [eventid, eventdata] : g_data[sec]) { //GetParam(*g_data.sections["Events"].GetValue(i),8); /*#ifdef RA2_MODE if(g_data.sections["EventsRA2"].FindIndex(eventid)>=0) eventdata=g_data.sections["EventsRA2"].values[eventid]; #endif*/ CString text = eventid + " " + GetParam(eventdata, 0); text.Replace("%1", ","); #ifdef RA2_MODE // MW 07/18/01 // for yuri mode, only check if it´s for RA2, else support it only if YR isnt´needed... if (GetParam(eventdata, 7) == "1" && (yuri_mode || !atoi(GetParam(eventdata, 9)))) { #else if (GetParam(eventdata, 6) == "1") { #endif m_EventType.AddString(text); } } int cur_sel = m_Event.GetCurSel(); while (m_Event.DeleteString(0) != CB_ERR); auto const& data = ini["Events"][m_currentTrigger]; int count = atoi(GetParam(data, 0)); for (i = 0; i < count; i++) { char c[50]; itoa(i, c, 10); CString s = TranslateStringACP("Event"); s += " "; s += c; m_Event.SetItemData(m_Event.AddString(s), i); } if (cur_sel < 0) { cur_sel = 0; } if (cur_sel >= count) { cur_sel = count - 1; } m_Event.SetCurSel(cur_sel); OnSelchangeEvent(); } // MW 07/20/01 void CTriggerEventsDlg::Clear() { m_EventType.SetWindowText(""); while (m_Parameter.DeleteString(0) != LB_ERR); m_ParamValue.SetWindowText(""); m_EventDescription.SetWindowText(""); }