Skip to content

Commit 75b61ef

Browse files
authored
Custom Data for Campaigns (#6906)
* campaign custom data * Assertion instead of assert
1 parent b8c3c56 commit 75b61ef

11 files changed

Lines changed: 89 additions & 7 deletions

File tree

code/mission/missioncampaign.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,10 @@ int mission_campaign_load(const char* filename, const char* full_path, player* p
518518
stuff_int( &(Campaign.flags) );
519519
}
520520

521+
if (optional_string("$begin_custom_data_map")) {
522+
parse_string_map(Campaign.custom_data, "$end_custom_data_map", "+Val:");
523+
}
524+
521525
// parse the optional ship/weapon information
522526
mission_campaign_get_sw_info();
523527

@@ -1259,6 +1263,7 @@ void mission_campaign_clear()
12591263
memset(Campaign.name, 0, NAME_LENGTH);
12601264
memset(Campaign.filename, 0, MAX_FILENAME_LEN);
12611265
Campaign.type = 0;
1266+
Campaign.custom_data.clear();
12621267
Campaign.flags = CF_DEFAULT_VALUE;
12631268
Campaign.num_missions = 0;
12641269
Campaign.num_missions_completed = 0;

code/mission/missioncampaign.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ class campaign
136136
SCP_vector<sexp_variable> red_alert_variables; // state of the variables in the previous mission of a Red Alert scenario.
137137
SCP_vector<sexp_container> persistent_containers; // These containers will be saved at the end of a mission
138138
SCP_vector<sexp_container> red_alert_containers; // state of the containers in the previous mission of a Red Alert scenario.
139+
SCP_map<SCP_string, SCP_string> custom_data; // Custom data for the campaign
139140

140141
campaign()
141142
: desc(nullptr), num_missions(0)

code/scripting/api/libs/mission.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3035,6 +3035,29 @@ ADE_FUNC(jumpToMission, l_Campaign, "string filename, [boolean hub]", "Jumps to
30353035
return ade_set_args(L, "b", success);
30363036
}
30373037

3038+
ADE_VIRTVAR(CustomData, l_Campaign, nullptr, "Gets the custom data table for this campaign", "table", "The campaign's custom data table")
3039+
{
3040+
if (ADE_SETTING_VAR) {
3041+
LuaError(L, "Setting Custom Data is not supported");
3042+
}
3043+
3044+
auto table = luacpp::LuaTable::create(L);
3045+
3046+
for (const auto& pair : Campaign.custom_data)
3047+
{
3048+
table.addValue(pair.first, pair.second);
3049+
}
3050+
3051+
return ade_set_args(L, "t", &table);
3052+
}
3053+
3054+
ADE_FUNC(hasCustomData, l_Campaign, nullptr, "Detects whether the campaign has any custom data", "boolean", "true if the campaign's custom_data is not empty, false otherwise")
3055+
{
3056+
3057+
bool result = !Campaign.custom_data.empty();
3058+
return ade_set_args(L, "b", result);
3059+
}
3060+
30383061
// TODO: add a proper indexer type that returns a handle
30393062
// something like ca.Mission[filename/index]
30403063

fred2/campaigneditordlg.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ BEGIN_MESSAGE_MAP(campaign_editor, CFormView)
103103
ON_EN_CHANGE(IDC_SUBSTITUTE_MAIN_HALL, OnChangeSubstituteMainHall)
104104
ON_EN_CHANGE(IDC_DEBRIEFING_PERSONA, OnChangeDebriefingPersona)
105105
ON_BN_CLICKED(IDC_CUSTOM_TECH_DB, OnCustomTechDB)
106+
ON_BN_CLICKED(IDC_OPEN_CUSTOM_DATA, OnCustomData)
106107
//}}AFX_MSG_MAP
107108
END_MESSAGE_MAP()
108109

@@ -951,6 +952,16 @@ void campaign_editor::OnCustomTechDB()
951952
Campaign.flags &= ~CF_CUSTOM_TECH_DATABASE;
952953
}
953954

955+
void campaign_editor::OnCustomData()
956+
{
957+
UpdateData(TRUE);
958+
959+
CustomDataDlg dlg(&Campaign.custom_data, this);
960+
dlg.DoModal();
961+
962+
UpdateData(FALSE);
963+
}
964+
954965
CString campaign_editor::GetPathWithoutFile() const
955966
{
956967
if (m_current_campaign_path.IsEmpty())

fred2/campaigneditordlg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class campaign_editor : public CFormView
115115
afx_msg void OnChangeSubstituteMainHall();
116116
afx_msg void OnChangeDebriefingPersona();
117117
afx_msg void OnCustomTechDB();
118+
afx_msg void OnCustomData();
118119
//}}AFX_MSG
119120
DECLARE_MESSAGE_MAP()
120121
};

fred2/customdatadlg.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ static char THIS_FILE[] = __FILE__;
2222
/////////////////////////////////////////////////////////////////////////////
2323
// CustomDataDlg dialog
2424

25-
CustomDataDlg::CustomDataDlg(CWnd* pParent /*=nullptr*/)
26-
: CDialog(CustomDataDlg::IDD, pParent)
25+
CustomDataDlg::CustomDataDlg(SCP_map<SCP_string, SCP_string>* data_ptr, CWnd* pParent /*=nullptr*/)
26+
: CDialog(CustomDataDlg::IDD, pParent), m_target_data(data_ptr)
2727
{
2828
}
2929

@@ -65,7 +65,8 @@ BOOL CustomDataDlg::OnInitDialog()
6565
CDialog::OnInitDialog();
6666

6767
// grab the existing list of custom data pairs and duplicate it. We only update it if the user clicks OK.
68-
m_custom_data = The_mission.custom_data;
68+
Assertion(m_target_data != nullptr, "Custom Data target is nullptr. Get a coder!");
69+
m_custom_data = *m_target_data;
6970

7071
update_data_lister();
7172

@@ -79,7 +80,8 @@ BOOL CustomDataDlg::OnInitDialog()
7980
void CustomDataDlg::OnButtonOk()
8081
{
8182
// now we set the custom data to our copy
82-
The_mission.custom_data = m_custom_data;
83+
Assertion(m_target_data != nullptr, "Custom Data target is nullptr. Get a coder!");
84+
*m_target_data = m_custom_data;
8385

8486
CDialog::OnOK();
8587
}
@@ -314,5 +316,6 @@ void CustomDataDlg::update_help_text(const SCP_string& description)
314316

315317
bool CustomDataDlg::query_modified() const
316318
{
317-
return The_mission.custom_data != m_custom_data;
319+
Assertion(m_target_data != nullptr, "Custom Data target is nullptr. Get a coder!");
320+
return *m_target_data != m_custom_data;
318321
}

fred2/customdatadlg.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
class CustomDataDlg : public CDialog {
1313
public:
14-
CustomDataDlg(CWnd* pParent = nullptr);
14+
CustomDataDlg(SCP_map<SCP_string, SCP_string>* data_ptr, CWnd* pParent = nullptr);
1515

1616
enum {
1717
IDD = IDD_EDIT_CUSTOM_DATA
@@ -55,6 +55,7 @@ class CustomDataDlg : public CDialog {
5555
private:
5656
bool query_modified() const;
5757

58+
SCP_map<SCP_string, SCP_string>* m_target_data = nullptr;
5859
SCP_map<SCP_string, SCP_string> m_custom_data;
5960

6061
// read-only view of data pair keys

fred2/fred.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,7 @@ BEGIN
17601760
LTEXT "Substitute",IDC_STATIC | UDS_ALIGNRIGHT,14,207,58,8
17611761
EDITTEXT IDC_SUBSTITUTE_MAIN_HALL,73,205,66,12,ES_AUTOHSCROLL
17621762
LTEXT "Branches",IDC_STATIC,7,229,31,8
1763+
PUSHBUTTON "Custom Data",IDC_OPEN_CUSTOM_DATA,181,203,71,15
17631764
CONTROL "Tree1",IDC_SEXP_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS | WS_BORDER | WS_HSCROLL | WS_TABSTOP,7,239,188,111,WS_EX_CLIENTEDGE
17641765
GROUPBOX "Branch Options",IDC_STATIC,202,229,61,64
17651766
PUSHBUTTON "Move Up",IDC_MOVE_UP,206,239,53,14,BS_CENTER,WS_EX_STATICEDGE

fred2/missionnotesdlg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ void CMissionNotesDlg::OnCustomData()
725725
{
726726
UpdateData(TRUE);
727727

728-
CustomDataDlg dlg;
728+
CustomDataDlg dlg(&The_mission.custom_data, this);
729729
dlg.DoModal();
730730

731731
UpdateData(FALSE);

fred2/missionsave.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,24 @@ int CFred_mission_save::save_campaign_file(const char *pathname)
13541354
fout(" %d\n", Campaign.flags);
13551355
}
13561356

1357+
if (Mission_save_format != FSO_FORMAT_RETAIL && !Campaign.custom_data.empty()) {
1358+
if (optional_string_fred("$begin_custom_data_map")) {
1359+
parse_comments(2);
1360+
} else {
1361+
fout("\n$begin_custom_data_map");
1362+
}
1363+
1364+
for (const auto& pair : Campaign.custom_data) {
1365+
fout("\n +Val: %s %s", pair.first.c_str(), pair.second.c_str());
1366+
}
1367+
1368+
if (optional_string_fred("$end_custom_data_map")) {
1369+
parse_comments();
1370+
} else {
1371+
fout("\n$end_custom_data_map");
1372+
}
1373+
}
1374+
13571375
// write out the ships and weapons which the player can start the campaign with
13581376
optional_string_fred("+Starting Ships: (");
13591377
parse_comments(2);

0 commit comments

Comments
 (0)