From b286e20dfd55b135a4aafe44288af7a709b1b57b Mon Sep 17 00:00:00 2001 From: Zero Fanker Date: Sun, 30 Jun 2024 23:14:39 +0800 Subject: [PATCH] Feature/team types (#72) --- MissionEditor/MissionEditor.rc | 228 +++++----- MissionEditor/TeamTypes.cpp | 402 +++++++++++++----- MissionEditor/TeamTypes.h | 150 +++++-- MissionEditor/data/FinalAlert2/FAData.ini | 17 + MissionEditor/data/FinalAlert2/FALanguage.ini | 51 ++- MissionEditor/resource.h | 21 +- 6 files changed, 626 insertions(+), 243 deletions(-) diff --git a/MissionEditor/MissionEditor.rc b/MissionEditor/MissionEditor.rc index b195ae3..8939e2f 100644 --- a/MissionEditor/MissionEditor.rc +++ b/MissionEditor/MissionEditor.rc @@ -718,13 +718,36 @@ BEGIN LTEXT "Name:",IDC_STATIC,10,51,30,10 EDITTEXT IDC_NAME,56,51,90,12,ES_AUTOHSCROLL LTEXT "Veteran level:",IDC_STATIC,10,66,45,15 + COMBOBOX IDC_VETERANLEVEL,56,66,90,60,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Priority:",IDC_STATIC,10,96,40,10 + EDITTEXT IDC_PRIORITY,56,96,90,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Max:",IDC_STATIC,10,111,30,10 + EDITTEXT IDC_MAX,56,111,90,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Techlevel:",IDC_STATIC,10,125,40,10 + COMBOBOX IDC_TECHLEVEL,56,125,91,72,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Group:",IDC_STATIC,156,51,30,10 + GROUPBOX "Selected team type",IDC_STATIC,6,37,290,161 + COMBOBOX IDC_GROUP,200,51,90,78,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Waypoint:",IDC_STATIC,156,66,40,10 + COMBOBOX IDC_WAYPOINT,200,66,90,80,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Script:",IDC_STATIC,156,81,40,10 + COMBOBOX IDC_SCRIPT,200,81,90,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Task force:",IDC_STATIC,156,96,40,10 + COMBOBOX IDC_TASKFORCE,200,96,90,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Tag:",IDC_STATIC,156,111,40,13 + COMBOBOX IDC_TAG,200,111,90,186,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "",IDC_LTRANSPORTWAYPOINT,156,126,40,17 + COMBOBOX IDC_TRANSPORTWAYPOINT,200,126,90,80,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Mind Control Decision:",IDC_STATIC,164,4,43,16,NOT WS_VISIBLE + COMBOBOX IDC_MINDCONTROLDECISION,209,6,92,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP + LTEXT "Mind Control Decision:",IDC_MCD_L,10,139,43,16,NOT WS_VISIBLE + LTEXT "House:",IDC_STATIC,10,81,35,10 + COMBOBOX IDC_HOUSE,56,81,90,62,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP CONTROL "Loadable",IDC_LOADABLE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,145,55,8 CONTROL "Full",IDC_FULL,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,155,55,8 CONTROL "Annoyance",IDC_ANNOYANCE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,164,55,10 CONTROL "Guard slower",IDC_GUARDSLOWER,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,175,55,8 CONTROL "Recruiter",IDC_RECRUITER,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,185,55,8 - LTEXT "House:",IDC_STATIC,10,81,35,10 - COMBOBOX IDC_HOUSE,56,81,90,62,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP CONTROL "Autocreate",IDC_AUTOCREATE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,125,145,55,8 CONTROL "Prebuild",IDC_PREBUILD,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,125,155,55,8 CONTROL "Reinforce",IDC_REINFORCE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,125,165,55,8 @@ -742,29 +765,6 @@ BEGIN "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,185,165,105,8 CONTROL "IsBaseDefense",IDC_ISBASEDEFENSE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,185,175,80,8 CONTROL "OnlyTargetHouseEnemy",IDC_ONLYTARGETHOUSEENEMY,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,185,185,100,8 - LTEXT "Priority:",IDC_STATIC,10,96,40,10 - EDITTEXT IDC_PRIORITY,56,96,90,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Max:",IDC_STATIC,10,111,30,10 - EDITTEXT IDC_MAX,56,111,90,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Techlevel:",IDC_STATIC,10,125,40,10 - COMBOBOX IDC_TECHLEVEL,56,125,91,72,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Group:",IDC_STATIC,156,51,30,10 - GROUPBOX "Selected team type",IDC_STATIC,6,37,290,161 - COMBOBOX IDC_GROUP,200,51,90,78,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Waypoint:",IDC_STATIC,156,66,40,10 - COMBOBOX IDC_WAYPOINT,200,66,90,80,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - LTEXT "Script:",IDC_STATIC,156,81,40,10 - COMBOBOX IDC_SCRIPT,200,81,90,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Task force:",IDC_STATIC,156,96,40,10 - COMBOBOX IDC_TASKFORCE,200,96,90,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_VETERANLEVEL,56,66,90,60,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Tag:",IDC_STATIC,156,111,40,13 - COMBOBOX IDC_TAG,200,111,90,186,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "",IDC_LTRANSPORTWAYPOINT,156,126,40,17 - COMBOBOX IDC_TRANSPORTWAYPOINT,200,126,90,80,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - LTEXT "Mind Control Decision:",IDC_STATIC,164,4,43,16,NOT WS_VISIBLE - COMBOBOX IDC_MINDCONTROLDECISION,209,6,92,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP - LTEXT "Mind Control Decision:",IDC_MCD_L,10,139,43,16,NOT WS_VISIBLE END #endif @@ -1291,68 +1291,71 @@ END #if defined(APSTUDIO_INVOKED) || defined(RA2_MODE) #if defined(APSTUDIO_INVOKED) -IDD_TEAMTYPES$(RA2_MODE) DIALOG 0, 0, 303, 215 +IDD_TEAMTYPES$(RA2_MODE) DIALOGEX 0, 0, 303, 286 #else -IDD_TEAMTYPES DIALOG 0, 0, 303, 215 +IDD_TEAMTYPES DIALOGEX 0, 0, 303, 286 #endif STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU CAPTION "Teams" -FONT 8, "Tahoma" +FONT 8, "Tahoma", 0, 0, 0x0 BEGIN - LTEXT "Team types connect a trigger with task forces",IDC_STATIC,6,5,290,10 - LTEXT "Team types:",IDC_STATIC,5,20,50,10 - COMBOBOX IDC_TEAMTYPES,55,20,155,174,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "New",IDC_NEWTEAMTYPE,261,20,35,15 - PUSHBUTTON "Delete",IDC_DELETETEAMTYPE,220,20,35,15 - LTEXT "Name:",IDC_STATIC,10,51,30,10 - EDITTEXT IDC_NAME,56,51,90,12,ES_AUTOHSCROLL - LTEXT "Veteran level:",IDC_STATIC,10,66,45,15 - CONTROL "Loadable",IDC_LOADABLE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,157,55,8 - CONTROL "Full",IDC_FULL,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,167,55,8 - CONTROL "Annoyance",IDC_ANNOYANCE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,176,55,10 - CONTROL "Guard slower",IDC_GUARDSLOWER,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,187,55,8 - CONTROL "Recruiter",IDC_RECRUITER,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,197,55,8 - LTEXT "House:",IDC_STATIC,10,81,35,10 - COMBOBOX IDC_HOUSE,56,81,90,62,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - CONTROL "Autocreate",IDC_AUTOCREATE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,125,157,55,8 - CONTROL "Prebuild",IDC_PREBUILD,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,125,167,55,8 - CONTROL "Reinforce",IDC_REINFORCE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,125,177,55,8 - CONTROL "Cargo plane",IDC_DROPPOD,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,65,157,55,8 - CONTROL "Whiner",IDC_WHINER,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,65,167,55,8 - CONTROL "Loose recruit",IDC_LOOSERECRUIT,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,65,177,55,8 - CONTROL "Aggressive",IDC_AGGRESSIVE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,65,187,55,8 - CONTROL "Suicide",IDC_SUICIDE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,65,197,55,8 - CONTROL "OnTransOnly",IDC_ONTRANSONLY,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,125,187,55,8 - CONTROL "AvoidThreats",IDC_AVOIDTHREATS,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,125,197,55,8 - CONTROL "Ion immune",IDC_IONIMMUNE,"Button",BS_AUTOCHECKBOX | BS_LEFT | NOT WS_VISIBLE | WS_TABSTOP,185,157,60,8 + LTEXT "Team types:",IDC_TEAMTYPE_TYPE,9,49,50,10 + COMBOBOX IDC_TEAMTYPES,55,49,235,174,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "New",IDC_NEWTEAMTYPE,181,63,35,15 + PUSHBUTTON "Clone",IDC_TEAMTYPE_COPY,218,63,35,15 + PUSHBUTTON "Delete",IDC_DELETETEAMTYPE,255,63,35,15 + LTEXT "Template:",IDC_TEAMTYPE_T_TXT,10,35,33,8 + COMBOBOX IDC_TEAMTYPE_TEMPLATE,55,35,235,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Name:",IDC_TEAMTYPE_P_NAME,10,90,30,10 + GROUPBOX "Selected team type",IDC_TEAMTYPE_GBOX,6,79,290,139 + EDITTEXT IDC_NAME,55,90,90,14,ES_AUTOHSCROLL + LTEXT "Veteran level:",IDC_TEAMTYPE_P_VLEVEL,10,105,45,14 + COMBOBOX IDC_VETERANLEVEL,55,105,90,60,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "House:",IDC_TEAMTYPE_P_HOUSE,10,120,35,10 + COMBOBOX IDC_HOUSE,55,120,90,62,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Priority:",IDC_TEAMTYPE_P_PRIORITY,10,135,40,10 + EDITTEXT IDC_PRIORITY,55,135,90,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Max:",IDC_TEAMTYPE_P_MAX,10,150,40,10 + EDITTEXT IDC_MAX,55,150,90,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Techlevel:",IDC_TEAMTYPE_P_TECHLEVEL,156,135,40,10 + COMBOBOX IDC_TECHLEVEL,200,135,90,72,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Group:",IDC_TEAMTYPE_P_GROUP,156,90,30,10 + COMBOBOX IDC_GROUP,200,90,90,78,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Waypoint:",IDC_TEAMTYPE_P_WAYP,156,105,40,10 + COMBOBOX IDC_WAYPOINT,200,105,90,80,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Script:",IDC_TEAMTYPE_P_SCRIPT,10,165,40,14 + COMBOBOX IDC_SCRIPT,55,165,235,186,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Task force:",IDC_TEAMTYPE_P_TASKFORCE,10,180,40,10 + COMBOBOX IDC_TASKFORCE,55,180,235,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Tag:",IDC_TEAMTYPE_P_TAG,10,195,40,10 + COMBOBOX IDC_TAG,55,195,235,205,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "Transport waypoint:",IDC_LTRANSPORTWAYPOINT,156,117,40,17 + COMBOBOX IDC_TRANSPORTWAYPOINT,200,120,90,80,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Mind Control Decision:",IDC_MCD_L,156,147,43,16 + COMBOBOX IDC_MINDCONTROLDECISION,200,150,90,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Team types connect a trigger with task forces",IDC_TEAMTYPE_DESC,11,5,290,29 + CONTROL "Loadable",IDC_LOADABLE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,220,60,8 + CONTROL "Full",IDC_FULL,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,230,60,8 + CONTROL "Annoyance",IDC_ANNOYANCE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,240,60,9 + CONTROL "Guard slower",IDC_GUARDSLOWER,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,250,60,8 + CONTROL "Recruiter",IDC_RECRUITER,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,10,260,60,8 + CONTROL "Autocreate",IDC_AUTOCREATE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,131,220,60,8 + CONTROL "Prebuild",IDC_PREBUILD,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,131,230,60,8 + CONTROL "Reinforce",IDC_REINFORCE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,131,240,60,8 + CONTROL "Cargo plane",IDC_DROPPOD,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,70,220,60,8 + CONTROL "Whiner",IDC_WHINER,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,70,230,60,8 + CONTROL "Loose recruit",IDC_LOOSERECRUIT,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,70,240,60,8 + CONTROL "Aggressive",IDC_AGGRESSIVE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,70,250,60,8 + CONTROL "Suicide",IDC_SUICIDE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,70,260,60,8 + CONTROL "OnTransOnly",IDC_ONTRANSONLY,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,131,250,60,8 + CONTROL "AvoidThreats",IDC_AVOIDTHREATS,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,131,260,60,8 + CONTROL "Ion immune",IDC_IONIMMUNE,"Button",BS_AUTOCHECKBOX | BS_LEFT | NOT WS_VISIBLE | WS_TABSTOP,197,220,48,8 CONTROL "TransportsReturnOnUnload",IDC_TRANSPORTRETURNSONUNLOAD, - "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,185,177,100,8 + "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,197,240,100,8 CONTROL "AreTeamMembersRecruitable",IDC_ARETEAMMEMBERSRECRUITABLE, - "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,185,167,105,8 - CONTROL "IsBaseDefense",IDC_ISBASEDEFENSE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,185,187,80,8 - CONTROL "OnlyTargetHouseEnemy",IDC_ONLYTARGETHOUSEENEMY,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,185,197,100,8 - LTEXT "Priority:",IDC_STATIC,10,96,40,10 - EDITTEXT IDC_PRIORITY,56,96,90,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Max:",IDC_STATIC,10,111,30,10 - EDITTEXT IDC_MAX,56,111,90,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Techlevel:",IDC_STATIC,10,125,40,10 - COMBOBOX IDC_TECHLEVEL,56,125,91,72,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Group:",IDC_STATIC,156,51,30,10 - GROUPBOX "Selected team type",IDC_STATIC,6,37,290,173 - COMBOBOX IDC_GROUP,200,51,90,78,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Waypoint:",IDC_STATIC,156,66,40,10 - COMBOBOX IDC_WAYPOINT,200,66,90,80,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - LTEXT "Script:",IDC_STATIC,156,81,40,10 - COMBOBOX IDC_SCRIPT,200,81,90,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Task force:",IDC_STATIC,156,96,40,10 - COMBOBOX IDC_TASKFORCE,200,96,90,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_VETERANLEVEL,56,66,90,60,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Tag:",IDC_STATIC,156,111,40,13 - COMBOBOX IDC_TAG,200,111,90,186,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "Transport waypoint:",IDC_LTRANSPORTWAYPOINT,156,126,40,17 - COMBOBOX IDC_TRANSPORTWAYPOINT,200,126,90,80,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - LTEXT "Mind Control Decision:",IDC_MCD_L,10,139,43,16 - COMBOBOX IDC_MINDCONTROLDECISION,55,140,92,205,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,197,230,102,8 + CONTROL "IsBaseDefense",IDC_ISBASEDEFENSE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,197,250,80,8 + CONTROL "OnlyTargetHouseEnemy",IDC_ONLYTARGETHOUSEENEMY,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,197,260,100,8 END #endif @@ -1958,6 +1961,34 @@ BEGIN "IDD_TEAMTYPES$(RA2_MODE)", DIALOG BEGIN + VERTGUIDE, 10 + VERTGUIDE, 55 + VERTGUIDE, 70 + VERTGUIDE, 131 + VERTGUIDE, 156 + VERTGUIDE, 197 + VERTGUIDE, 200 + VERTGUIDE, 245 + VERTGUIDE, 290 + BOTTOMMARGIN, 285 + HORZGUIDE, 34 + HORZGUIDE, 35 + HORZGUIDE, 49 + HORZGUIDE, 70 + HORZGUIDE, 79 + HORZGUIDE, 90 + HORZGUIDE, 105 + HORZGUIDE, 120 + HORZGUIDE, 135 + HORZGUIDE, 150 + HORZGUIDE, 165 + HORZGUIDE, 180 + HORZGUIDE, 196 + HORZGUIDE, 232 + HORZGUIDE, 230 + HORZGUIDE, 240 + HORZGUIDE, 250 + HORZGUIDE, 260 END IDD_NEWMAPTYPE, DIALOG @@ -2807,6 +2838,12 @@ IDD_TEAMTYPES$(RA2_MODE) DLGINIT IDD_TEAMTYPES DLGINIT #endif BEGIN + IDC_VETERANLEVEL, 0x403, 2, 0 +0x0031, + IDC_VETERANLEVEL, 0x403, 2, 0 +0x0032, + IDC_VETERANLEVEL, 0x403, 2, 0 +0x0033, IDC_TECHLEVEL, 0x403, 2, 0 0x0030, IDC_TECHLEVEL, 0x403, 2, 0 @@ -2831,26 +2868,6 @@ BEGIN 0x3031, "\000" IDC_GROUP, 0x403, 3, 0 0x312d, "\000" - IDC_VETERANLEVEL, 0x403, 2, 0 -0x0031, - IDC_VETERANLEVEL, 0x403, 2, 0 -0x0032, - IDC_VETERANLEVEL, 0x403, 2, 0 -0x0033, - IDC_MINDCONTROLDECISION, 0x403, 17, 0 -0x2030, 0x202d, 0x443c, 0x6e6f, 0x7427, 0x6320, 0x7261, 0x3e65, "\000" - IDC_MINDCONTROLDECISION, 0x403, 16, 0 -0x2031, 0x202d, 0x6441, 0x2064, 0x6f54, 0x5420, 0x6165, 0x006d, - IDC_MINDCONTROLDECISION, 0x403, 19, 0 -0x2032, 0x202d, 0x7550, 0x2074, 0x6e69, 0x4720, 0x6972, 0x646e, 0x7265, -"\000" - IDC_MINDCONTROLDECISION, 0x403, 23, 0 -0x2033, 0x202d, 0x7550, 0x2074, 0x6e69, 0x4220, 0x6f69, 0x5220, 0x6165, -0x7463, 0x726f, "\000" - IDC_MINDCONTROLDECISION, 0x403, 15, 0 -0x2034, 0x202d, 0x6f47, 0x7420, 0x206f, 0x7548, 0x746e, "\000" - IDC_MINDCONTROLDECISION, 0x403, 15, 0 -0x2035, 0x202d, 0x6f44, 0x4e20, 0x746f, 0x6968, 0x676e, "\000" 0 END #endif @@ -3560,6 +3577,17 @@ BEGIN 0 END +#if defined(APSTUDIO_INVOKED) || defined(RA2_MODE) +#if defined(APSTUDIO_INVOKED) +IDD_TEAMTYPES$(RA2_MODE) AFX_DIALOG_LAYOUT +#else +IDD_TEAMTYPES AFX_DIALOG_LAYOUT +#endif +BEGIN + 0 +END +#endif + ///////////////////////////////////////////////////////////////////////////// // diff --git a/MissionEditor/TeamTypes.cpp b/MissionEditor/TeamTypes.cpp index f708c73..f9c186c 100644 --- a/MissionEditor/TeamTypes.cpp +++ b/MissionEditor/TeamTypes.cpp @@ -76,7 +76,6 @@ CTeamTypes::CTeamTypes() : CDialog(CTeamTypes::IDD) m_VeteranLevel = _T(""); m_Tag = _T(""); m_TransportWaypoint = _T(""); - m_MindControlDecision = _T(""); //}}AFX_DATA_INIT } @@ -84,11 +83,154 @@ CTeamTypes::~CTeamTypes() { } +void CTeamTypes::translateUI() +{ + TranslateWindowCaption(*this, "TeamTypesCaption"); + + TranslateDlgItem(*this, IDC_TEAMTYPE_COPY, "TeamTypesCopy"); + TranslateDlgItem(*this, IDC_TEAMTYPE_DESC, "TeamTypesDesc"); + TranslateDlgItem(*this, IDC_TEAMTYPE_T_TXT, "TeamTypesTemplate"); + TranslateDlgItem(*this, IDC_TEAMTYPE_TYPE, "TeamTypesType"); + TranslateDlgItem(*this, IDC_NEWTEAMTYPE, "TeamTypesNew"); + TranslateDlgItem(*this, IDC_DELETETEAMTYPE, "TeamTypesDelete"); + TranslateDlgItem(*this, IDC_TEAMTYPE_GBOX, "TeamTypesSelected"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_NAME, "TeamTypesName"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_GROUP, "TeamTypesGroup"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_VLEVEL, "TeamTypesVeteranLevel"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_WAYP, "TeamTypesWaypoint"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_HOUSE, "TeamTypesHouse"); + TranslateDlgItem(*this, IDC_LTRANSPORTWAYPOINT, "TeamTypesTransWaypoint"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_PRIORITY, "TeamTypesPriority"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_TECHLEVEL, "TeamTypesTechLevel"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_MAX, "TeamTypesMax"); + TranslateDlgItem(*this, IDC_MCD_L, "TeamTypesMCDecision"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_TAG, "TeamTypesTag"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_SCRIPT, "TeamTypesScript"); + TranslateDlgItem(*this, IDC_TEAMTYPE_P_TASKFORCE, "TeamTypesTaskforce"); + TranslateDlgItem(*this, IDC_LOADABLE, "TeamTypesLoadable"); + TranslateDlgItem(*this, IDC_FULL, "TeamTypesFull"); + TranslateDlgItem(*this, IDC_ANNOYANCE, "TeamTypesAnnoyance"); + TranslateDlgItem(*this, IDC_GUARDSLOWER, "TeamTypesGuardSlower"); + TranslateDlgItem(*this, IDC_RECRUITER, "TeamTypesRecruiter"); + TranslateDlgItem(*this, IDC_AUTOCREATE, "TeamTypesAutocreate"); + TranslateDlgItem(*this, IDC_PREBUILD, "TeamTypesPrebuild"); + TranslateDlgItem(*this, IDC_REINFORCE, "TeamTypesReinforce"); + TranslateDlgItem(*this, IDC_DROPPOD, "TeamTypesDropped"); + TranslateDlgItem(*this, IDC_WHINER, "TeamTypesWhiner"); + TranslateDlgItem(*this, IDC_LOOSERECRUIT, "TeamTypesLooseRecruit"); + TranslateDlgItem(*this, IDC_AGGRESSIVE, "TeamTypesAggressive"); + TranslateDlgItem(*this, IDC_SUICIDE, "TeamTypesSuicide"); + TranslateDlgItem(*this, IDC_ONTRANSONLY, "TeamTypesOnTransOnly"); + TranslateDlgItem(*this, IDC_AVOIDTHREATS, "TeamTypesAvoidThreats"); + TranslateDlgItem(*this, IDC_IONIMMUNE, "TeamTypesIonImmune"); + TranslateDlgItem(*this, IDC_TRANSPORTRETURNSONUNLOAD, "TeamTypesTransportsReturnOnUnload"); + TranslateDlgItem(*this, IDC_ARETEAMMEMBERSRECRUITABLE, "TeamTypesAreTeamMembersRecruitable"); + TranslateDlgItem(*this, IDC_ISBASEDEFENSE, "TeamTypesIsBaseDefense"); + TranslateDlgItem(*this, IDC_ONLYTARGETHOUSEENEMY, "TeamTypesOnlyTargetHouseEnemy"); +} + +inline void TeamTemplate::assignInteger(int& val, const CString& str) +{ + val = INIHelper::StringToInteger(str, val); +} +inline void TeamTemplate::assignBool(bool& val, const CString& str) +{ + val = INIHelper::StringToBool(str, val); +} + +TeamTemplate::TeamTemplate(std::vector&& input) noexcept : + m_displayName(std::move(input[0])) +{ + m_params.Name = std::move(input[1]); + assignInteger(m_params.VeteranLevel, input[2]); + assignInteger(m_params.Group, input[5]); + assignInteger(m_params.Priority,input[3]); + assignInteger(m_params.TechLevel ,input[6]); + assignInteger(m_params.Max, input[4]); +#ifdef RA2_MODE + assignInteger(m_params.MindControlDecision, input[7]); +#endif + assignBool(m_params.Loadable, input[8]); + assignBool(m_params.Full, input[9]); + assignBool(m_params.Annoyance, input[10]); + assignBool(m_params.GuardSlower, input[11]); + assignBool(m_params.Recruiter, input[12]); + assignBool(m_params.Droppod, input[13]); + assignBool(m_params.Whiner, input[14]); + assignBool(m_params.LooseRecruit, input[15]); + assignBool(m_params.Aggressive, input[16]); + assignBool(m_params.Suicide, input[17]); + assignBool(m_params.Autocreate, input[18]); + assignBool(m_params.Prebuild, input[19]); + assignBool(m_params.Reinforce, input[20]); + assignBool(m_params.OnTransOnly, input[21]); + assignBool(m_params.AvoidThreats, input[22]); + assignBool(m_params.AreTeamMembersRecruitable, input[23]); + assignBool(m_params.TransportsReturnOnUnload, input[24]); + assignBool(m_params.IsBaseDefense, input[25]); + + assignBool(m_params.OnlyTargetHouseEnemy, input[26]); +#if defined(RA2_MODE) && 0 + assignBool(m_params.UseTransportOrigin, input[27]); +#endif + +} + +void CTeamTypes::reloadTemplates() +{ + auto const& sec = g_data["TeamTemplates"]; + auto const count = sec.GetInteger("Counts"); + auto&& defName = sec.GetStringOr("DefaultName", "Default"); + + m_templates.push_back({ std::move(defName), { .Name = "New teamtype" } }); + + auto parseTemplate = [this, &sec](const CString& id) -> bool { + auto&& elements = INIHelper::Split(sec.GetString(id)); + if (elements.size() != 27) { + errstream << "[team type template] content fragments less than 27" << std::endl; + return false; + } + m_templates.push_back(std::move(elements)); + return true; + }; + + auto offset = 0; + // try from 0. If no 0, try from 1 + if (!parseTemplate("0")) { + errstream << "[team type template] could not parse content from index 0" << std::endl; + offset = 1; + } + + CString idStr; + for (auto idx = 0; idx < count; ++idx) { + idStr.Format("%d", idx + offset); + if (!parseTemplate(idStr)) { + errstream << "[team type template] could not parse content from index " << idStr << std::endl; + } + } + + // load template into list + ASSERT(m_templates.size() > 0); + auto idx = 0; + for (auto const& templ : m_templates) { + m_Template.InsertString(idx++, templ.Desc()); + } + m_Template.SetCurSel(0); +} + +BOOL CTeamTypes::OnInitDialog() +{ + auto const ret = CDialog::OnInitDialog(); + initMCDecisionComboBox(); + translateUI(); + return ret; +} + void CTeamTypes::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTeamTypes) - DDX_Control(pDX, IDC_MCD_L, m_MCD_L); + DDX_Control(pDX, IDC_TEAMTYPE_TEMPLATE, m_Template); DDX_Control(pDX, IDC_TEAMTYPES, m_TeamTypes); DDX_Check(pDX, IDC_AGGRESSIVE, m_Aggressive); DDX_Check(pDX, IDC_ANNOYANCE, m_Annoyance); @@ -122,7 +264,7 @@ void CTeamTypes::DoDataExchange(CDataExchange* pDX) DDX_CBString(pDX, IDC_VETERANLEVEL, m_VeteranLevel); DDX_CBString(pDX, IDC_TAG, m_Tag); DDX_CBString(pDX, IDC_TRANSPORTWAYPOINT, m_TransportWaypoint); - DDX_CBString(pDX, IDC_MINDCONTROLDECISION, m_MindControlDecision); + DDX_Control(pDX, IDC_MINDCONTROLDECISION, m_MindControlDecision); //}}AFX_DATA_MAP } @@ -170,6 +312,7 @@ BEGIN_MESSAGE_MAP(CTeamTypes, CDialog) ON_CBN_EDITCHANGE(IDC_MINDCONTROLDECISION, OnEditchangeMindcontroldecision) ON_CBN_KILLFOCUS(IDC_MINDCONTROLDECISION, OnKillfocusMindcontroldecision) //}}AFX_MSG_MAP + ON_BN_CLICKED(IDC_TEAMTYPE_COPY, &CTeamTypes::OnBnClickedTeamtypeCopy) END_MESSAGE_MAP() BOOL stob(const char* s) @@ -183,78 +326,29 @@ BOOL stob(const char* s) CString btos(BOOL b) { CString s = "no"; - if (b == TRUE) s = "yes"; + if (b == TRUE) { + s = "yes"; + } return s; } int letter2number(char let) { int reply = let - 'A'; - /*if(let=='A')reply=0; - if(let=='B')reply=1; - if(let=='C')reply=2; - if(let=='D')reply=3; - if(let=='E')reply=4; - if(let=='F')reply=5; - if(let=='G')reply=6; - if(let=='H')reply=7; - if(let=='I')reply=8; - if(let=='J')reply=9; - if(let=='K')reply=10; - if(let=='L')reply=11; - if(let=='M')reply=12; - if(let=='N')reply=13; - if(let=='O')reply=14; - if(let=='P')reply=15; - if(let=='Q')reply=16; - if(let=='R')reply=17; - if(let=='S')reply=18; - if(let=='T')reply=19; - if(let=='U')reply=20; - if(let=='V')reply=21; - if(let=='W')reply=22; - if(let=='X')reply=23; - if(let=='Y')reply=24; - if(let=='Z')reply=25;*/ return reply; } char number2letter(int let) { int reply = let + 'A'; - /*if(let==0)reply='A'; - if(let==1)reply='B'; - if(let==2)reply='C'; - if(let==3)reply='D'; - if(let==4)reply='E'; - if(let==5)reply='F'; - if(let==6)reply='G'; - if(let==7)reply='H'; - if(let==8)reply='I'; - if(let==9)reply='J'; - if(let==10)reply='K'; - if(let==11)reply='L'; - if(let==12)reply='M'; - if(let==13)reply='N'; - if(let==14)reply='O'; - if(let==15)reply='P'; - if(let==16)reply='Q'; - if(let==17)reply='R'; - if(let==18)reply='S'; - if(let==19)reply='T'; - if(let==20)reply='U'; - if(let==21)reply='V'; - if(let==22)reply='W'; - if(let==23)reply='X'; - if(let==24)reply='Y'; - if(let==25)reply='Z';*/ - return reply; } int GetWaypoint(const char* c) { - if (strlen(c) == 0) return -1; + if (strlen(c) == 0) { + return -1; + } int i; int res = 0; for (i = 0; i < strlen(c); i++) { @@ -266,7 +360,9 @@ int GetWaypoint(const char* c) CString GetWaypoint(int n) { - if (n == -1) return (CString)(""); + if (n == -1) { + return (CString)(""); + } int i, e; for (i = -1; i < 26; i++) { for (e = 0; e < 26; e++) { @@ -275,12 +371,16 @@ CString GetWaypoint(int n) if (i == -1) { c[0] = number2letter(e); c[1] = 0; - if (GetWaypoint(c) == n) return c; + if (GetWaypoint(c) == n) { + return c; + } } else { c[0] = number2letter(i); c[1] = number2letter(e); c[2] = 0; - if (GetWaypoint(c) == n) return c; + if (GetWaypoint(c) == n) { + return c; + } } } @@ -293,9 +393,13 @@ CString GetWaypoint(int n) // Behandlungsroutinen für Nachrichten CTeamTypes void CTeamTypes::UpdateDialog() { + if (m_templates.empty()) { + reloadTemplates(); + } + if (!yuri_mode) { GetDlgItem(IDC_MINDCONTROLDECISION)->ShowWindow(SW_HIDE); - m_MCD_L.ShowWindow(SW_HIDE); + GetDlgItem(IDC_MCD_L)->ShowWindow(SW_HIDE); } CIniFile& ini = Map->GetIniFile(); @@ -341,7 +445,6 @@ void CTeamTypes::UpdateDialog() m_TransportReturnsOnUnload = 0; m_TransportWaypoint = ""; m_VeteranLevel = ""; - m_MindControlDecision = ""; UpdateData(FALSE); @@ -426,6 +529,27 @@ void CTeamTypes::UpdateDialog() } +void CTeamTypes::initMCDecisionComboBox() +{ + ComboBoxHelper::Clear(m_MindControlDecision); + m_MindControlDecision.AddString(TranslateStringACP("0 - ")); + m_MindControlDecision.AddString(TranslateStringACP("1 - Add To Team")); + m_MindControlDecision.AddString(TranslateStringACP("2 - Put in Grinder")); + m_MindControlDecision.AddString(TranslateStringACP("3 - Put in Bio Reactor")); + m_MindControlDecision.AddString(TranslateStringACP("4 - Go to Hunt")); + m_MindControlDecision.AddString(TranslateStringACP("5 - Do Nothing")); +} + +int CTeamTypes::getMCDecision() +{ + return std::max(m_MindControlDecision.GetCurSel(), 0); +} + +void CTeamTypes::setMCDection(const int decision) +{ + m_MindControlDecision.SetCurSel(decision); +} + void CTeamTypes::OnSelchangeTeamtypes() { CIniFile& ini = Map->GetIniFile(); @@ -488,7 +612,7 @@ void CTeamTypes::OnSelchangeTeamtypes() m_VeteranLevel = sec.GetString("VeteranLevel"); if (yuri_mode) { - m_MindControlDecision = sec.GetString("MindControlDecision"); + setMCDection(sec.GetInteger("MindControlDecision")); } @@ -772,7 +896,9 @@ void CTeamTypes::OnShowWindow(BOOL bShow, UINT nStatus) OnKillfocusTag(); #ifdef RA2_MODE OnKillfocusTransportwaypoint(); - if (yuri_mode) OnKillfocusMindcontroldecision(); + if (yuri_mode) { + OnKillfocusMindcontroldecision(); + } #endif } } @@ -1101,7 +1227,7 @@ void CTeamTypes::OnOnlytargethouseenemy() CString GetFree(const char* section); -void CTeamTypes::OnNewteamtype() +void CTeamTypes::addTeamtype(const TeamTypeParams& params) { CIniFile& ini = Map->GetIniFile(); @@ -1112,42 +1238,56 @@ void CTeamTypes::OnNewteamtype() // TODO: change default value ini.SetString("TeamTypes", p, id); CIniFileSection& s = ini.AddSection(id); - s.SetString("Name", "New teamtype"); - s.SetInteger("VeteranLevel", 1); - s.SetBool("Loadable", false); - s.SetBool("Full", true); - s.SetBool("Annoyance", false); - s.SetBool("GuardSlower", false); - s.SetBool("Recruiter", false); - s.SetBool("Autocreate", true); - s.SetBool("Prebuild", false); - s.SetBool("Reinforce", false); - s.SetBool("Droppod", false); - s.SetBool("Whiner", false); - s.SetBool("LooseRecruit", false); - s.SetBool("Aggressive", false); - s.SetBool("Suicide", false); - s.SetInteger("Priority", 5); - s.SetInteger("Max", 5); - s.SetInteger("TechLevel", 0); - s.SetInteger("Group", -1); - s.SetBool("OnTransOnly", false); - s.SetBool("AvoidThreats", false); - s.SetBool("IonImmune", false); - s.SetBool("TransportsReturnOnUnload", false); - s.SetBool("AreTeamMembersRecruitable", false); - s.SetBool("IsBaseDefense", false); - s.SetBool("OnlyTargetHouseEnemy", false); -#ifdef RA2_MODE - s.SetBool("UseTransportOrigin", false); - if (yuri_mode) { - s.SetInteger("MindControlDecision", 0); + s.SetString("Name", params.Name); + s.SetInteger("VeteranLevel", params.VeteranLevel); + s.SetBool("Loadable", params.Loadable); + s.SetBool("Full", params.Full); + s.SetBool("Annoyance", params.Annoyance); + s.SetBool("GuardSlower", params.GuardSlower); + s.SetBool("Recruiter", params.Recruiter); + s.SetBool("Autocreate", params.Autocreate); + s.SetBool("Prebuild", params.Prebuild); + s.SetBool("Reinforce", params.Reinforce); + s.SetBool("Droppod", params.Droppod); + s.SetBool("Whiner", params.Whiner); + s.SetBool("LooseRecruit", params.LooseRecruit); + s.SetBool("Aggressive", params.Aggressive); + s.SetBool("Suicide", params.Suicide); + s.SetInteger("Priority", params.Priority); + s.SetInteger("Max", params.Max); + s.SetInteger("TechLevel", params.TechLevel); + s.SetInteger("Group", params.Group); + s.SetInteger("Waypoint", params.Waypoint); + s.SetInteger("TransportWaypoint", params.TransportWaypoint); + s.SetBool("OnTransOnly", params.OnTransOnly); + s.SetBool("AvoidThreats", params.AvoidThreats); + s.SetBool("IonImmune", params.IonImmune); + s.SetBool("TransportsReturnOnUnload", params.TransportsReturnOnUnload); + s.SetBool("AreTeamMembersRecruitable", params.AreTeamMembersRecruitable); + s.SetBool("IsBaseDefense", params.IsBaseDefense); + s.SetBool("OnlyTargetHouseEnemy", params.OnlyTargetHouseEnemy); + + if (!params.House.IsEmpty()) { + s.SetString("House", params.House); + } + if (!params.TaskForce.IsEmpty()) { + s.SetString("TaskForce", params.TaskForce); + } + if (!params.Script.IsEmpty()) { + s.SetString("Script", params.Script); + } + if (!params.Tag.IsEmpty()) { + s.SetString("Tag", params.Tag); } +#ifdef RA2_MODE + s.SetBool("UseTransportOrigin", params.UseTransportOrigin); + if (yuri_mode) { + s.SetInteger("MindControlDecision", params.MindControlDecision); + } #endif - //UpdateDialog(); ((CFinalSunDlg*)theApp.m_pMainWnd)->UpdateDialogs(TRUE); @@ -1177,6 +1317,69 @@ void CTeamTypes::OnNewteamtype() OnKillfocusTaskforce(); } +void CTeamTypes::OnNewteamtype() +{ + //errstream << "Add Script" << std::endl; + int curTemplateIndex = m_Template.GetCurSel(); + ASSERT(curTemplateIndex >= 0); + auto const& curTemplate = m_templates[curTemplateIndex]; + //errstream << "Now using Script Template: " << curTemplate.Name() << std::endl; + addTeamtype(curTemplate.Params()); +} + +void CTeamTypes::OnBnClickedTeamtypeCopy() +{ + auto const& ini = Map->GetIniFile(); + auto curTeamType = GetText(&m_TeamTypes); + TruncSpace(curTeamType); + + if (curTeamType.IsEmpty()) { + return; + } + + auto const& sec = ini.GetSection(curTeamType); + addTeamtype({ + .Name = sec.GetString("Name") + " Clone", + .House = sec.GetString("House"), + .TaskForce = sec.GetString("TaskForce"), + .Script = sec.GetString("Script"), + .Tag = sec.GetString("Tag"), + .VeteranLevel = sec.GetInteger("VeteranLevel"), + .Group = sec.GetInteger("Group"), + .Priority = sec.GetInteger("Priority"), + .TechLevel = sec.GetInteger("TechLevel"), + .Max = sec.GetInteger("Max"), + .Waypoint = sec.GetInteger("Waypoint"), + .TransportWaypoint = sec.GetInteger("TransportWaypoint"), +#ifdef RA2_MODE + .MindControlDecision = sec.GetInteger("MindControlDecision"), +#endif + .Aggressive = sec.GetBool("Aggressive"), + .Annoyance = sec.GetBool("Annoyance"), + .AreTeamMembersRecruitable = sec.GetBool("AreTeamMembersRecruitable"), + .Autocreate = sec.GetBool("Autocreate"), + .AvoidThreats = sec.GetBool("AvoidThreats"), + .Droppod = sec.GetBool("Droppod"), + .Full = sec.GetBool("Full"), + .GuardSlower = sec.GetBool("GuardSlower"), + .IonImmune = sec.GetBool("IonImmune"), + .IsBaseDefense = sec.GetBool("IsBaseDefense"), + .Loadable = sec.GetBool("Loadable"), + .LooseRecruit = sec.GetBool("LooseRecruit"), + .OnlyTargetHouseEnemy = sec.GetBool("OnlyTargetHouseEnemy"), + .OnTransOnly = sec.GetBool("OnTransOnly"), + .Prebuild = sec.GetBool("Prebuild"), + .Recruiter = sec.GetBool("Recruiter"), + .Reinforce = sec.GetBool("Reinforce"), + .Suicide = sec.GetBool("Suicide"), + .TransportsReturnOnUnload = sec.GetBool("TransportsReturnOnUnload"), + .Whiner = sec.GetBool("Whiner"), +#ifdef RA2_MODE + .UseTransportOrigin = sec.GetBool("UseTransportOrigin"), +#endif + }); +} + void CTeamTypes::OnEditchangeTag() { CIniFile& ini = Map->GetIniFile(); @@ -1252,12 +1455,11 @@ void CTeamTypes::OnEditchangeMindcontroldecision() TruncSpace(str); auto sec = ini.TryGetSection(str); ASSERT(sec != nullptr); - CString tmp = m_MindControlDecision; - TruncSpace(tmp); - sec->SetString("MindControlDecision", std::move(tmp)); + sec->SetInteger("MindControlDecision", getMCDecision()); } void CTeamTypes::OnKillfocusMindcontroldecision() { OnEditchangeMindcontroldecision(); } + diff --git a/MissionEditor/TeamTypes.h b/MissionEditor/TeamTypes.h index 491b200..de88ec9 100644 --- a/MissionEditor/TeamTypes.h +++ b/MissionEditor/TeamTypes.h @@ -33,6 +33,68 @@ ///////////////////////////////////////////////////////////////////////////// // Dialogfeld CTeamTypes +struct TeamTypeParams +{ + CString Name; + CString House; + CString TaskForce; + CString Script; + CString Tag; + int VeteranLevel{ 1 }; + int Group{ -1 }; + int Priority{ 5 }; + int TechLevel{}; + int Max{ 1 }; + int Waypoint{}; + int TransportWaypoint{}; +#ifdef RA2_MODE + int MindControlDecision{}; +#endif + bool Aggressive{}; + bool Annoyance{}; + bool AreTeamMembersRecruitable{}; + bool Autocreate{}; + bool AvoidThreats{}; + bool Droppod{}; + bool Full{}; + bool GuardSlower{}; + bool IonImmune{}; + bool IsBaseDefense{}; + bool Loadable{}; + bool LooseRecruit{}; + bool OnlyTargetHouseEnemy{}; + bool OnTransOnly{}; + bool Prebuild{}; + bool Recruiter{}; + bool Reinforce{}; + bool Suicide{}; + bool TransportsReturnOnUnload{}; + bool Whiner{}; +#ifdef RA2_MODE + bool UseTransportOrigin{}; +#endif +}; + +class TeamTemplate +{ +public: + TeamTemplate(std::vector&& input) noexcept; + // used for default template + TeamTemplate(CString&& name, TeamTypeParams&& params) noexcept : + m_displayName(std::move(name)), + m_params(std::move(params)) + {} + + const CString& Desc() const { return m_displayName; } + const TeamTypeParams& Params() const { return m_params; } + +private: + static void assignInteger(int& val, const CString& str); + static void assignBool(bool& val, const CString& str); + + CString m_displayName; + TeamTypeParams m_params; +}; class CTeamTypes : public CDialog { @@ -45,54 +107,23 @@ public: ~CTeamTypes(); // Dialogfelddaten - //{{AFX_DATA(CTeamTypes) enum { IDD = IDD_TEAMTYPES }; - CStatic m_MCD_L; - CComboBox m_TeamTypes; - BOOL m_Aggressive; - BOOL m_Annoyance; - BOOL m_AreTeamMembersRecruitable; - BOOL m_Autocreate; - BOOL m_AvoidThreats; - BOOL m_Droppod; - BOOL m_Full; - CString m_Group; - BOOL m_GuardSlower; - CString m_House; - BOOL m_IonImmune; - BOOL m_IsBaseDefense; - BOOL m_Loadable; - BOOL m_LooseRecruit; - CString m_Max; - CString m_Name; - BOOL m_OnlyTargetHouseEnemy; - BOOL m_OnTransOnly; - BOOL m_Prebuild; - CString m_Priority; - BOOL m_Recruiter; - BOOL m_Reinforce; - CString m_Script; - BOOL m_Suicide; - CString m_TaskForce; - CString m_TechLevel; - BOOL m_TransportReturnsOnUnload; - CString m_Waypoint; - BOOL m_Whiner; - CString m_VeteranLevel; - CString m_Tag; - CString m_TransportWaypoint; - CString m_MindControlDecision; - //}}AFX_DATA - // Überschreibungen // Der Klassen-Assistent generiert virtuelle Funktionsüberschreibungen //{{AFX_VIRTUAL(CTeamTypes) protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV-Unterstützung + virtual BOOL OnInitDialog() override; + virtual void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV-Unterstützung //}}AFX_VIRTUAL + void addTeamtype(const TeamTypeParams& params); + void translateUI(); + void initMCDecisionComboBox(); + void reloadTemplates(); + void setMCDection(const int decision); + int getMCDecision(); -// Implementierung + // Implementierung protected: // Generierte Nachrichtenzuordnungsfunktionen //{{AFX_MSG(CTeamTypes) @@ -143,9 +174,48 @@ protected: afx_msg void OnKillfocusTransportwaypoint(); afx_msg void OnEditchangeMindcontroldecision(); afx_msg void OnKillfocusMindcontroldecision(); + afx_msg void OnBnClickedTeamtypeCopy(); //}}AFX_MSG DECLARE_MESSAGE_MAP() +private: + CComboBox m_Template; + CComboBox m_TeamTypes; + BOOL m_Aggressive; + BOOL m_Annoyance; + BOOL m_AreTeamMembersRecruitable; + BOOL m_Autocreate; + BOOL m_AvoidThreats; + BOOL m_Droppod; + BOOL m_Full; + CString m_Group; + BOOL m_GuardSlower; + CString m_House; + BOOL m_IonImmune; + BOOL m_IsBaseDefense; + BOOL m_Loadable; + BOOL m_LooseRecruit; + CString m_Max; + CString m_Name; + BOOL m_OnlyTargetHouseEnemy; + BOOL m_OnTransOnly; + BOOL m_Prebuild; + CString m_Priority; + BOOL m_Recruiter; + BOOL m_Reinforce; + CString m_Script; + BOOL m_Suicide; + CString m_TaskForce; + CString m_TechLevel; + BOOL m_TransportReturnsOnUnload; + CString m_Waypoint; + BOOL m_Whiner; + CString m_VeteranLevel; + CString m_Tag; + CString m_TransportWaypoint; + CComboBox m_MindControlDecision; + + std::vector m_templates; }; //{{AFX_INSERT_LOCATION}} diff --git a/MissionEditor/data/FinalAlert2/FAData.ini b/MissionEditor/data/FinalAlert2/FAData.ini index df4a84f..aac77ed 100644 --- a/MissionEditor/data/FinalAlert2/FAData.ini +++ b/MissionEditor/data/FinalAlert2/FAData.ini @@ -45,6 +45,23 @@ Counts=5 4=装载部队卸载攻击,New unload script,6,3,0,8,2,39,0,20,0,50,120,0,0 5=装载入载具并攻击,New load script,3,21,EMPTY,14,EMPTY,0,0 +;===TeamTemplates=== +;X=UIName, Name, Experience Level, Priority, Max, Group, TechLevel, Mind-control Result, Checkbox1, Checkbox2, ..., Checkbox19 +;Checkbox order matrix: +; |1 6 11 | +; |2 7 12 16| +; |3 8 13 17| +; |4 9 14 18| +; |5 10 15 19| + +;By Sandman +[TeamTemplates] +DefaultName=默认 +Counts=3 +1=空降部队,New Paratroop Team,1,5,5,-1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 +2=AI生产小队,New AI Production Team,1,5,10,-1,5,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0 +3=突击小队,New Offense Team,1,5,5,-1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0 + ; not NOSURFACES: ;[BuildingVoxelTurretsRA2] ;GTGCANX=-1 diff --git a/MissionEditor/data/FinalAlert2/FALanguage.ini b/MissionEditor/data/FinalAlert2/FALanguage.ini index ba678db..b062867 100644 --- a/MissionEditor/data/FinalAlert2/FALanguage.ini +++ b/MissionEditor/data/FinalAlert2/FALanguage.ini @@ -1349,7 +1349,7 @@ ScriptTypesAddScript=添加 ScriptTypesCopyScript=复制 ScriptTypesDelScript=删除 ScriptsCaption=小队脚本 -ScriptTypesDesc=脚本类型允许你定义如一作战小队从一个路径点移动到另一路径点。一个脚本类型与小队类型相关联(不是特遣部队!)\n欲应用模板,请在下拉列表里选中一个预置模板,然后点击“新建”。\n如果预置列表里啥都没有,可以点击“刷新”以重新载入。 +ScriptTypesDesc=脚本类型允许你定义如一作战小队从一个路径点移动到另一路径点。一个脚本类型与小队类型相关联(不是特遣部队!)\n欲应用模板,请在下拉列表里选中一个预置模板,然后点击“新建”。\n ScriptTypesSelectedScript=脚本类型: ScriptTypesName=名称: ScriptTypesActions=行为: @@ -1363,6 +1363,55 @@ ScriptTypesActionDesc=说明: ScriptTypesSelectedTemplate=模板: ScriptTypesParamExtDesc=附加参数: +; team types +TeamTypesCaption=小队选项 +TeamTypesTemplate=模板: +TeamTypesType=小队类型: +TeamTypesDesc=作战小队将特遣部队和脚本联系起来,并用于AI触发等场合。\n欲应用模板,请在下拉列表里选中一个预置模板,然后点击“新建”。\n +TeamTypesNew=新建 +TeamTypesCopy=复制 +TeamTypesDelete=删除 +TeamTypesSelected=当前选中的类型 +TeamTypesName=名称: +TeamTypesGroup=分组: +TeamTypesVeteranLevel=经验等级: +TeamTypesWaypoint=路径点: +TeamTypesTransWaypoint=运输机生成路径点: +TeamTypesHouse=所属方: +TeamTypesPriority=优先权: +TeamTypesTechLevel=科技等级: +TeamTypesMax=实例上限: +TeamTypesMCDecision=心控结果: +TeamTypesTag=触发标签: +TeamTypesScript=动作脚本: +TeamTypesTaskforce=成员类型: +TeamTypesLoadable=可搭载乘客 +TeamTypesFull=乘客在载具内 +TeamTypesAnnoyance=骚扰模式 +TeamTypesGuardSlower=消极反击 +TeamTypesRecruiter=无视分组 +TeamTypesAutocreate=考虑建造 +TeamTypesPrebuild=提前建造 +TeamTypesReinforce=阵亡自动候补 +TeamTypesDropped=空投入场 +TeamTypesWhiner=平民哀嚎 +TeamTypesLooseRecruit=吸纳闲置单位 +TeamTypesAggressive=激进模式 +TeamTypesSuicide=无脑冲锋 +TeamTypesOnTransOnly=被动运输模式 +TeamTypesAvoidThreats=绕开威胁热点 +TeamTypesIonImmune=离子风暴免疫 +TeamTypesTransportsReturnOnUnload=运输器下客返程 +TeamTypesAreTeamMembersRecruitable=成员可被征调 +TeamTypesIsBaseDefense=基地防御专用 +TeamTypesOnlyTargetHouseEnemy=仅攻击当前敌对方 +0 - =0 - <随意> +1 - Add To Team=1 - 加入小队 +2 - Put in Grinder=2 - 放入回收厂 +3 - Put in Bio Reactor=3 - 放入生化反应炉 +4 - Go to Hunt=4 - 寻敌 +5 - Do Nothing=5 - 不作操作 + ; iso view IsoCaption=地图视图 diff --git a/MissionEditor/resource.h b/MissionEditor/resource.h index ab6e75a..544abb6 100644 --- a/MissionEditor/resource.h +++ b/MissionEditor/resource.h @@ -520,20 +520,37 @@ #define IDC_TRIGGER_OPTION_TYPE_STR 1464 #define IDC_SCRIPT_CK_INSERT 1464 #define IDC_TRIGGER_OPTION_NAME 1465 +#define IDC_TEAMTYPE_TEMPLATE 1465 #define IDC_TRIGGER_OPTION_HOUSE 1466 +#define IDC_TEAMTYPE_T_TXT 1466 #define IDC_TRIGGER_OPTION_ATTACHED_TRIGGER 1467 +#define IDC_TEAMTYPE_COPY 1467 #define IDC_TRIGGER_OPTION_TRIGGER_DIS_TIP 1468 +#define IDC_TEAMTYPE_DESC 1468 #define IDC_MAP_D_WIDTH 1469 +#define IDC_TEAMTYPE_TYPE 1469 #define IDC_MAP_D_HEIGHT 1470 +#define IDC_TEAMTYPE_GBOX 1470 #define IDC_SCTIPTTYPE_INRO 1471 +#define IDC_TEAMTYPE_P_NAME 1471 #define IDC_SCRIPTTYPE_TYPE 1472 +#define IDC_TEAMTYPE_P_GROUP 1472 #define IDC_SCRIPTTYPE_NAME 1473 +#define IDC_TEAMTYPE_P_VLEVEL 1473 #define IDC_SCRIPTTYPE_ACTIONS 1474 +#define IDC_TEAMTYPE_P_WAYP 1474 #define IDC_SCRIPTTYPE_ACTIONTYPE 1475 +#define IDC_TEAMTYPE_P_HOUSE 1475 #define IDC_SCRIPTTYPE_DESC 1476 +#define IDC_TEAMTYPE_P_PRIORITY 1476 #define IDD_TERRAINBAR_TG 1477 +#define IDC_TEAMTYPE_P_TECHLEVEL 1477 #define IDD_TERRAINBAR_OS 1478 +#define IDC_TEAMTYPE_P_MAX 1478 #define IDC_SCRIPT_TEMPLATE_DSC 1479 +#define IDC_TEAMTYPE_P_TAG 1479 +#define IDC_TEAMTYPE_P_SCRIPT 1480 +#define IDC_TEAMTYPE_P_TASKFORCE 1481 #define ID_FILE_OPENMAP 40001 #define ID_FILE_SAVEAS 40002 #define ID_FILE_QUIT 40003 @@ -628,9 +645,9 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 300 +#define _APS_NEXT_RESOURCE_VALUE 301 #define _APS_NEXT_COMMAND_VALUE 40144 -#define _APS_NEXT_CONTROL_VALUE 1465 +#define _APS_NEXT_CONTROL_VALUE 1482 #define _APS_NEXT_SYMED_VALUE 111 #endif #endif