2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Fred2/MissionNotesDlg.cpp $
15 * Mission notes editor dialog box handling code
18 * Revision 1.3 2002/06/09 04:41:16 relnev
19 * added copyright header
21 * Revision 1.2 2002/05/07 03:16:44 theoddone33
22 * The Great Newline Fix
24 * Revision 1.1.1.1 2002/05/03 03:28:08 root
28 * 6 8/23/99 6:21p Jefff
29 * added "no traitor" option to missions (and fred)
31 * 5 8/23/99 5:04p Jefff
32 * Added new mission flag to disable built-in messages from playing.
33 * Added fred support as well.
35 * 4 3/24/99 4:05p Dave
36 * Put in support for assigning the player to a specific squadron with a
37 * specific logo. Preliminary work for doing pos/orient checksumming in
38 * multiplayer to reduce bandwidth.
40 * 3 2/23/99 2:32p Dave
41 * First run of oldschool dogfight mode.
43 * 2 10/07/98 6:28p Dave
44 * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
45 * Fred. Globalized mission and campaign file extensions. Removed Silent
46 * Threat specific code.
48 * 1 10/07/98 3:01p Dave
50 * 1 10/07/98 3:00p Dave
52 * 23 6/17/98 2:47p Hoffoss
53 * Changed so missions are single, multi or training. Not supporting
54 * combos of the above anymore (in Fred).
56 * 22 5/25/98 12:16p Hoffoss
57 * Removed dogfight option from dialog. No longer supported.
59 * 21 5/18/98 1:56a Allender
60 * respawn limit to 999 max
62 * 20 5/05/98 11:05p Allender
63 * ability to flag mission as "no promotion" where promotions and badges
64 * are *not* granted even if they should be. Slight fix to multiplayer
65 * problem where locking_subsys is wrong for players current target
67 * 19 4/03/98 12:17a Allender
68 * new sexpression to detect departed or destroyed. optionally disallow
69 * support ships. Allow docking with escape pods
71 * 18 3/26/98 5:24p Allender
72 * put in respawn edit box into mission notes dialog. Made loading of
73 * missions/campaign happen when first entering the game setup screen.
75 * 17 3/18/98 3:17p Allender
76 * fix scramble checkbox
78 * 16 3/18/98 10:27a Allender
79 * fixed bug with missions always being tagged a single player regardless
82 * 15 3/16/98 8:27p Allender
83 * Fred support for two new AI flags -- kamikaze and no dynamic goals.
85 * 14 3/09/98 4:30p Allender
86 * multiplayer secondary weapon changes. red-alert and cargo-known-delay
87 * sexpressions. Add time cargo revealed to ship structure
89 * 13 2/09/98 9:25p Allender
90 * team v team support. multiple pools and breifings
92 * 12 2/04/98 4:32p Allender
93 * support for multiple briefings and debriefings. Changes to mission
94 * type (now a bitfield). Bitfield defs for multiplayer modes
96 * 11 1/02/98 4:55p Hoffoss
97 * Added support for Mission_all_attack flag to Fred and loading/saving
100 * 10 9/30/97 5:56p Hoffoss
101 * Added music selection combo boxes to Fred.
103 * 9 8/11/97 3:19p Hoffoss
104 * Implemented mission description.
106 * 8 6/11/97 2:14p Hoffoss
107 * Added game type (mission type) selection to Fred.
109 * 7 5/20/97 2:28p Hoffoss
110 * Added message box queries for close window operation on all modal
113 * 6 5/06/97 2:43p Hoffoss
114 * Fixed bug in Mission notes dialog, where window wasn't being destroyed.
116 * 5 4/17/97 2:01p Hoffoss
117 * All dialog box window states are saved between sessions now.
119 * 4 2/21/97 5:34p Hoffoss
120 * Added extensive modification detection and fixed a bug in initial
123 * 3 2/17/97 5:28p Hoffoss
124 * Checked RCS headers, added them were missing, changing description to
125 * something better, etc where needed.
133 #include "missionnotesdlg.h"
134 #include "management.h"
135 #include "eventmusic.h"
138 #define new DEBUG_NEW
140 static char THIS_FILE[] = __FILE__;
143 #define NO_SQUAD "<none>"
145 // module globals to hold button information
146 CButton *coop, *team, *dogfight;
148 /////////////////////////////////////////////////////////////////////////////
149 // CMissionNotesDlg dialog
151 CMissionNotesDlg::CMissionNotesDlg(CWnd* pParent /*=NULL*/) : CDialog(CMissionNotesDlg::IDD, pParent)
153 //{{AFX_DATA_INIT(CMissionNotesDlg)
156 m_mission_notes = _T("");
157 m_designer_name = _T("");
158 m_mission_title = _T("");
159 m_mission_desc = _T("");
160 m_squad_filename = _T("");
161 m_squad_name = _T(NO_SQUAD);
167 m_disallow_support = FALSE;
168 m_no_promotion = FALSE;
169 m_no_builtin_msgs = FALSE;
170 m_no_traitor = FALSE;
174 void CMissionNotesDlg::DoDataExchange(CDataExchange* pDX)
176 CDialog::DoDataExchange(pDX);
177 //{{AFX_DATA_MAP(CMissionNotesDlg)
178 DDX_Control(pDX, IDC_RESPAWN_SPIN, m_respawn_spin);
179 DDX_Text(pDX, IDC_CREATED, m_created);
180 DDX_Text(pDX, IDC_MODIFIED, m_modified);
181 DDX_Text(pDX, IDC_MISSION_NOTES, m_mission_notes);
182 DDX_Text(pDX, IDC_DESIGNER_NAME, m_designer_name);
183 DDX_Text(pDX, IDC_MISSION_TITLE, m_mission_title);
184 DDX_Text(pDX, IDC_MISSION_DESC, m_mission_desc);
185 DDX_Text(pDX, IDC_SQUAD_LOGO, m_squad_filename);
186 DDX_Text(pDX, IDC_SQUAD_NAME, m_squad_name);
187 DDX_CBIndex(pDX, IDC_MUSIC, m_music);
188 DDX_Check(pDX, IDC_FULL_WAR, m_full_war);
189 DDX_Check(pDX, IDC_RED_ALERT, m_red_alert);
190 DDX_Check(pDX, IDC_SCRAMBLE, m_scramble);
191 DDX_Text(pDX, IDC_RESPAWNS, m_num_respawns);
192 DDV_MinMaxUInt(pDX, m_num_respawns, 0, 999);
193 DDX_Check(pDX, IDC_SUPPORT_ALLOWED, m_disallow_support);
194 DDX_Check(pDX, IDC_NO_PROMOTION, m_no_promotion);
195 DDX_Check(pDX, IDC_DISABLE_BUILTIN_MSGS, m_no_builtin_msgs);
196 DDX_Check(pDX, IDC_NO_TRAITOR, m_no_traitor);
200 BEGIN_MESSAGE_MAP(CMissionNotesDlg, CDialog)
201 //{{AFX_MSG_MAP(CMissionNotesDlg)
203 ON_BN_CLICKED(IDC_TRAINING, OnTraining)
204 ON_BN_CLICKED(IDC_MULTI, OnMulti)
205 ON_BN_CLICKED(IDC_SINGLE, OnSingle)
206 ON_BN_CLICKED(IDC_SQUAD_LOGO_BUTTON, OnSquadLogo)
210 /////////////////////////////////////////////////////////////////////////////
211 // CMissionNotesDlg message handlers
213 int CMissionNotesDlg::query_modified()
215 if (m_mission_title != m_mission_title_orig){
218 if (m_designer_name != m_designer_name_orig){
221 if (m_mission_notes != m_mission_notes_orig){
224 if (m_mission_desc != m_mission_desc_orig){
227 if (Current_soundtrack_num != m_music - 1){
230 if (Mission_all_attack != m_full_war){
237 void CMissionNotesDlg::OnOK()
239 int new_m_type, flags, is_multi = 0, is_training = 0, is_single = 0;
242 is_single = (((CButton *) GetDlgItem(IDC_SINGLE))->GetCheck() == 1);
243 is_multi = (((CButton *) GetDlgItem(IDC_MULTI))->GetCheck() == 1);
244 is_training = (((CButton *) GetDlgItem(IDC_TRAINING))->GetCheck() == 1);
246 // deal with changing the mission type. Code is done this way since training missions
247 // just override anything else.
250 new_m_type = MISSION_TYPE_TRAINING;
253 new_m_type = MISSION_TYPE_SINGLE;
257 new_m_type |= MISSION_TYPE_MULTI;
258 if (coop->GetCheck()){
259 new_m_type |= MISSION_TYPE_MULTI_COOP;
260 } else if (team->GetCheck()){
261 new_m_type |= MISSION_TYPE_MULTI_TEAMS;
262 } else if(dogfight->GetCheck()){
263 new_m_type |= MISSION_TYPE_MULTI_DOGFIGHT;
265 Int3(); // get allender -- multiplayer mode not set!!!
271 MessageBox("You must select the game type: training, single, or multiplayer", "Error");
275 MODIFY(The_mission.game_type, new_m_type );
276 MODIFY(The_mission.red_alert, m_red_alert );
277 MODIFY(The_mission.scramble, m_scramble );
278 MODIFY(The_mission.num_respawns, (int)m_num_respawns );
279 MODIFY(The_mission.disallow_support, (int)m_disallow_support);
281 // set the flags for no promotion
282 flags = The_mission.flags;
283 if ( m_no_promotion ) {
284 The_mission.flags |= MISSION_FLAG_NO_PROMOTION;
286 The_mission.flags &= ~MISSION_FLAG_NO_PROMOTION;
289 // set flags for no builtin messages
290 if ( m_no_builtin_msgs ) {
291 The_mission.flags |= MISSION_FLAG_NO_BUILTIN_MSGS;
293 The_mission.flags &= ~MISSION_FLAG_NO_BUILTIN_MSGS;
296 // set no traitor flags
297 if ( m_no_traitor ) {
298 The_mission.flags |= MISSION_FLAG_NO_TRAITOR;
300 The_mission.flags &= ~MISSION_FLAG_NO_TRAITOR;
303 if ( flags != The_mission.flags ){
307 string_copy(The_mission.name, m_mission_title, NAME_LENGTH, 1);
308 string_copy(The_mission.author, m_designer_name, NAME_LENGTH, 1);
309 deconvert_multiline_string(The_mission.notes, m_mission_notes, NOTES_LENGTH);
310 deconvert_multiline_string(The_mission.mission_desc, m_mission_desc, MISSION_DESC_LENGTH);
313 if(m_squad_name == CString(NO_SQUAD)){
314 strcpy(The_mission.squad_name, "");
315 strcpy(The_mission.squad_filename, "");
317 string_copy(The_mission.squad_name, m_squad_name, NAME_LENGTH);
318 string_copy(The_mission.squad_filename, m_squad_filename, MAX_FILENAME_LEN);
321 MODIFY(Current_soundtrack_num, m_music - 1);
322 MODIFY(Mission_all_attack, m_full_war);
323 if (query_modified()){
327 theApp.record_window_data(&Mission_notes_wnd_data, this);
329 // update the Num_teams variable accoriding to mission types
331 if ( (The_mission.game_type & MISSION_TYPE_MULTI) && (The_mission.game_type & MISSION_TYPE_MULTI_TEAMS) ){
338 void CMissionNotesDlg::OnCancel()
340 theApp.record_window_data(&Mission_notes_wnd_data, this);
344 BOOL CMissionNotesDlg::OnInitDialog()
349 // set up the radio box states
350 coop = (CButton *)GetDlgItem(IDC_COOP);
351 team = (CButton *)GetDlgItem(IDC_TEAMVTEAM);
352 dogfight = (CButton *)GetDlgItem(IDC_DOGFIGHT);
354 m_mission_title_orig = m_mission_title = _T(The_mission.name);
355 m_designer_name_orig = m_designer_name = _T(The_mission.author);
356 m_created = _T(The_mission.created);
357 m_modified = _T(The_mission.modified);
358 m_mission_notes_orig = m_mission_notes = convert_multiline_string(The_mission.notes);
359 m_mission_desc_orig = m_mission_desc = convert_multiline_string(The_mission.mission_desc);
360 m_red_alert = The_mission.red_alert;
361 m_scramble = The_mission.scramble;
362 m_disallow_support = The_mission.disallow_support;
363 m_no_promotion = (The_mission.flags & MISSION_FLAG_NO_PROMOTION) ? 1 : 0;
364 m_no_builtin_msgs = (The_mission.flags & MISSION_FLAG_NO_BUILTIN_MSGS) ? 1 : 0;
365 m_no_traitor = (The_mission.flags & MISSION_FLAG_NO_TRAITOR) ? 1 : 0;
366 CDialog::OnInitDialog();
368 box = (CComboBox *) GetDlgItem(IDC_MUSIC);
369 box->AddString("None");
370 for (i=0; i<Num_soundtracks; i++){
371 box->AddString(Soundtracks[i].name);
375 if(strlen(The_mission.squad_name) > 0){
376 m_squad_name = _T(The_mission.squad_name);
377 m_squad_filename = _T(The_mission.squad_filename);
379 m_squad_name = _T(NO_SQUAD);
380 m_squad_filename = _T("");
383 m_type = The_mission.game_type;
384 m_music = Current_soundtrack_num + 1;
385 m_full_war = Mission_all_attack;
387 // set up the game type checkboxes accoring to m_type
388 if ( m_type & MISSION_TYPE_SINGLE ){
389 ((CButton *) GetDlgItem(IDC_SINGLE))->SetCheck(1);
392 // for multiplayer -- be sure to assign a default type if not already assigned.
393 if ( m_type & MISSION_TYPE_MULTI ){
394 ((CButton *) GetDlgItem(IDC_MULTI))->SetCheck(1);
397 if ( m_type & MISSION_TYPE_TRAINING ){
398 ((CButton *) GetDlgItem(IDC_TRAINING))->SetCheck(1);
401 // we need to set one of these three multiplayer modes so interface looks correct
402 if ( !(m_type & (MISSION_TYPE_MULTI_COOP | MISSION_TYPE_MULTI_DOGFIGHT | MISSION_TYPE_MULTI_TEAMS)) ){
403 m_type |= MISSION_TYPE_MULTI_COOP;
406 if ( m_type & MISSION_TYPE_MULTI_COOP ){
408 } else if ( m_type & MISSION_TYPE_MULTI_TEAMS ){
410 } else if ( m_type & MISSION_TYPE_MULTI_DOGFIGHT ){
411 dogfight->SetCheck(1);
413 Int3(); // get allender -- multiplayer mode not set!!!
416 m_respawn_spin.SetRange(0, 99);
417 m_num_respawns = The_mission.num_respawns;
421 theApp.init_window(&Mission_notes_wnd_data, this);
425 void CMissionNotesDlg::OnClose()
429 if (query_modified()) {
430 z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
444 // when training button is set, we need to disable all other buttons
445 void CMissionNotesDlg::OnTraining()
451 void CMissionNotesDlg::OnMulti()
457 void CMissionNotesDlg::OnSingle()
463 void CMissionNotesDlg::set_types()
467 // when training is checked, no other type is active
468 if (((CButton *) GetDlgItem(IDC_MULTI))->GetCheck() == 1){
472 coop->EnableWindow(enable);
473 team->EnableWindow(enable);
474 dogfight->EnableWindow(enable);
475 GetDlgItem(IDC_RESPAWNS)->EnableWindow(enable);
476 GetDlgItem(IDC_RESPAWN_SPIN)->EnableWindow(enable);
479 void CMissionNotesDlg::OnSquadLogo()
481 CString pcx_filename;
484 // get list of squad images
485 z = cfile_push_chdir(CF_TYPE_SQUAD_IMAGES_MAIN);
486 CFileDialog dlg(TRUE, "pcx", pcx_filename, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "Pcx Files (*.pcx)|*.pcx");
488 // if we have a result
489 if (dlg.DoModal() == IDOK) {
490 m_squad_filename = dlg.GetFileName();
492 m_squad_filename = _T("");