2 * $Logfile: /Freespace2/code/Fred2/MissionNotesDlg.cpp $
7 * Mission notes editor dialog box handling code
10 * Revision 1.2 2002/05/07 03:16:44 theoddone33
11 * The Great Newline Fix
13 * Revision 1.1.1.1 2002/05/03 03:28:08 root
17 * 6 8/23/99 6:21p Jefff
18 * added "no traitor" option to missions (and fred)
20 * 5 8/23/99 5:04p Jefff
21 * Added new mission flag to disable built-in messages from playing.
22 * Added fred support as well.
24 * 4 3/24/99 4:05p Dave
25 * Put in support for assigning the player to a specific squadron with a
26 * specific logo. Preliminary work for doing pos/orient checksumming in
27 * multiplayer to reduce bandwidth.
29 * 3 2/23/99 2:32p Dave
30 * First run of oldschool dogfight mode.
32 * 2 10/07/98 6:28p Dave
33 * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
34 * Fred. Globalized mission and campaign file extensions. Removed Silent
35 * Threat specific code.
37 * 1 10/07/98 3:01p Dave
39 * 1 10/07/98 3:00p Dave
41 * 23 6/17/98 2:47p Hoffoss
42 * Changed so missions are single, multi or training. Not supporting
43 * combos of the above anymore (in Fred).
45 * 22 5/25/98 12:16p Hoffoss
46 * Removed dogfight option from dialog. No longer supported.
48 * 21 5/18/98 1:56a Allender
49 * respawn limit to 999 max
51 * 20 5/05/98 11:05p Allender
52 * ability to flag mission as "no promotion" where promotions and badges
53 * are *not* granted even if they should be. Slight fix to multiplayer
54 * problem where locking_subsys is wrong for players current target
56 * 19 4/03/98 12:17a Allender
57 * new sexpression to detect departed or destroyed. optionally disallow
58 * support ships. Allow docking with escape pods
60 * 18 3/26/98 5:24p Allender
61 * put in respawn edit box into mission notes dialog. Made loading of
62 * missions/campaign happen when first entering the game setup screen.
64 * 17 3/18/98 3:17p Allender
65 * fix scramble checkbox
67 * 16 3/18/98 10:27a Allender
68 * fixed bug with missions always being tagged a single player regardless
71 * 15 3/16/98 8:27p Allender
72 * Fred support for two new AI flags -- kamikaze and no dynamic goals.
74 * 14 3/09/98 4:30p Allender
75 * multiplayer secondary weapon changes. red-alert and cargo-known-delay
76 * sexpressions. Add time cargo revealed to ship structure
78 * 13 2/09/98 9:25p Allender
79 * team v team support. multiple pools and breifings
81 * 12 2/04/98 4:32p Allender
82 * support for multiple briefings and debriefings. Changes to mission
83 * type (now a bitfield). Bitfield defs for multiplayer modes
85 * 11 1/02/98 4:55p Hoffoss
86 * Added support for Mission_all_attack flag to Fred and loading/saving
89 * 10 9/30/97 5:56p Hoffoss
90 * Added music selection combo boxes to Fred.
92 * 9 8/11/97 3:19p Hoffoss
93 * Implemented mission description.
95 * 8 6/11/97 2:14p Hoffoss
96 * Added game type (mission type) selection to Fred.
98 * 7 5/20/97 2:28p Hoffoss
99 * Added message box queries for close window operation on all modal
102 * 6 5/06/97 2:43p Hoffoss
103 * Fixed bug in Mission notes dialog, where window wasn't being destroyed.
105 * 5 4/17/97 2:01p Hoffoss
106 * All dialog box window states are saved between sessions now.
108 * 4 2/21/97 5:34p Hoffoss
109 * Added extensive modification detection and fixed a bug in initial
112 * 3 2/17/97 5:28p Hoffoss
113 * Checked RCS headers, added them were missing, changing description to
114 * something better, etc where needed.
122 #include "missionnotesdlg.h"
123 #include "management.h"
124 #include "eventmusic.h"
127 #define new DEBUG_NEW
129 static char THIS_FILE[] = __FILE__;
132 #define NO_SQUAD "<none>"
134 // module globals to hold button information
135 CButton *coop, *team, *dogfight;
137 /////////////////////////////////////////////////////////////////////////////
138 // CMissionNotesDlg dialog
140 CMissionNotesDlg::CMissionNotesDlg(CWnd* pParent /*=NULL*/) : CDialog(CMissionNotesDlg::IDD, pParent)
142 //{{AFX_DATA_INIT(CMissionNotesDlg)
145 m_mission_notes = _T("");
146 m_designer_name = _T("");
147 m_mission_title = _T("");
148 m_mission_desc = _T("");
149 m_squad_filename = _T("");
150 m_squad_name = _T(NO_SQUAD);
156 m_disallow_support = FALSE;
157 m_no_promotion = FALSE;
158 m_no_builtin_msgs = FALSE;
159 m_no_traitor = FALSE;
163 void CMissionNotesDlg::DoDataExchange(CDataExchange* pDX)
165 CDialog::DoDataExchange(pDX);
166 //{{AFX_DATA_MAP(CMissionNotesDlg)
167 DDX_Control(pDX, IDC_RESPAWN_SPIN, m_respawn_spin);
168 DDX_Text(pDX, IDC_CREATED, m_created);
169 DDX_Text(pDX, IDC_MODIFIED, m_modified);
170 DDX_Text(pDX, IDC_MISSION_NOTES, m_mission_notes);
171 DDX_Text(pDX, IDC_DESIGNER_NAME, m_designer_name);
172 DDX_Text(pDX, IDC_MISSION_TITLE, m_mission_title);
173 DDX_Text(pDX, IDC_MISSION_DESC, m_mission_desc);
174 DDX_Text(pDX, IDC_SQUAD_LOGO, m_squad_filename);
175 DDX_Text(pDX, IDC_SQUAD_NAME, m_squad_name);
176 DDX_CBIndex(pDX, IDC_MUSIC, m_music);
177 DDX_Check(pDX, IDC_FULL_WAR, m_full_war);
178 DDX_Check(pDX, IDC_RED_ALERT, m_red_alert);
179 DDX_Check(pDX, IDC_SCRAMBLE, m_scramble);
180 DDX_Text(pDX, IDC_RESPAWNS, m_num_respawns);
181 DDV_MinMaxUInt(pDX, m_num_respawns, 0, 999);
182 DDX_Check(pDX, IDC_SUPPORT_ALLOWED, m_disallow_support);
183 DDX_Check(pDX, IDC_NO_PROMOTION, m_no_promotion);
184 DDX_Check(pDX, IDC_DISABLE_BUILTIN_MSGS, m_no_builtin_msgs);
185 DDX_Check(pDX, IDC_NO_TRAITOR, m_no_traitor);
189 BEGIN_MESSAGE_MAP(CMissionNotesDlg, CDialog)
190 //{{AFX_MSG_MAP(CMissionNotesDlg)
192 ON_BN_CLICKED(IDC_TRAINING, OnTraining)
193 ON_BN_CLICKED(IDC_MULTI, OnMulti)
194 ON_BN_CLICKED(IDC_SINGLE, OnSingle)
195 ON_BN_CLICKED(IDC_SQUAD_LOGO_BUTTON, OnSquadLogo)
199 /////////////////////////////////////////////////////////////////////////////
200 // CMissionNotesDlg message handlers
202 int CMissionNotesDlg::query_modified()
204 if (m_mission_title != m_mission_title_orig){
207 if (m_designer_name != m_designer_name_orig){
210 if (m_mission_notes != m_mission_notes_orig){
213 if (m_mission_desc != m_mission_desc_orig){
216 if (Current_soundtrack_num != m_music - 1){
219 if (Mission_all_attack != m_full_war){
226 void CMissionNotesDlg::OnOK()
228 int new_m_type, flags, is_multi = 0, is_training = 0, is_single = 0;
231 is_single = (((CButton *) GetDlgItem(IDC_SINGLE))->GetCheck() == 1);
232 is_multi = (((CButton *) GetDlgItem(IDC_MULTI))->GetCheck() == 1);
233 is_training = (((CButton *) GetDlgItem(IDC_TRAINING))->GetCheck() == 1);
235 // deal with changing the mission type. Code is done this way since training missions
236 // just override anything else.
239 new_m_type = MISSION_TYPE_TRAINING;
242 new_m_type = MISSION_TYPE_SINGLE;
246 new_m_type |= MISSION_TYPE_MULTI;
247 if (coop->GetCheck()){
248 new_m_type |= MISSION_TYPE_MULTI_COOP;
249 } else if (team->GetCheck()){
250 new_m_type |= MISSION_TYPE_MULTI_TEAMS;
251 } else if(dogfight->GetCheck()){
252 new_m_type |= MISSION_TYPE_MULTI_DOGFIGHT;
254 Int3(); // get allender -- multiplayer mode not set!!!
260 MessageBox("You must select the game type: training, single, or multiplayer", "Error");
264 MODIFY(The_mission.game_type, new_m_type );
265 MODIFY(The_mission.red_alert, m_red_alert );
266 MODIFY(The_mission.scramble, m_scramble );
267 MODIFY(The_mission.num_respawns, (int)m_num_respawns );
268 MODIFY(The_mission.disallow_support, (int)m_disallow_support);
270 // set the flags for no promotion
271 flags = The_mission.flags;
272 if ( m_no_promotion ) {
273 The_mission.flags |= MISSION_FLAG_NO_PROMOTION;
275 The_mission.flags &= ~MISSION_FLAG_NO_PROMOTION;
278 // set flags for no builtin messages
279 if ( m_no_builtin_msgs ) {
280 The_mission.flags |= MISSION_FLAG_NO_BUILTIN_MSGS;
282 The_mission.flags &= ~MISSION_FLAG_NO_BUILTIN_MSGS;
285 // set no traitor flags
286 if ( m_no_traitor ) {
287 The_mission.flags |= MISSION_FLAG_NO_TRAITOR;
289 The_mission.flags &= ~MISSION_FLAG_NO_TRAITOR;
292 if ( flags != The_mission.flags ){
296 string_copy(The_mission.name, m_mission_title, NAME_LENGTH, 1);
297 string_copy(The_mission.author, m_designer_name, NAME_LENGTH, 1);
298 deconvert_multiline_string(The_mission.notes, m_mission_notes, NOTES_LENGTH);
299 deconvert_multiline_string(The_mission.mission_desc, m_mission_desc, MISSION_DESC_LENGTH);
302 if(m_squad_name == CString(NO_SQUAD)){
303 strcpy(The_mission.squad_name, "");
304 strcpy(The_mission.squad_filename, "");
306 string_copy(The_mission.squad_name, m_squad_name, NAME_LENGTH);
307 string_copy(The_mission.squad_filename, m_squad_filename, MAX_FILENAME_LEN);
310 MODIFY(Current_soundtrack_num, m_music - 1);
311 MODIFY(Mission_all_attack, m_full_war);
312 if (query_modified()){
316 theApp.record_window_data(&Mission_notes_wnd_data, this);
318 // update the Num_teams variable accoriding to mission types
320 if ( (The_mission.game_type & MISSION_TYPE_MULTI) && (The_mission.game_type & MISSION_TYPE_MULTI_TEAMS) ){
327 void CMissionNotesDlg::OnCancel()
329 theApp.record_window_data(&Mission_notes_wnd_data, this);
333 BOOL CMissionNotesDlg::OnInitDialog()
338 // set up the radio box states
339 coop = (CButton *)GetDlgItem(IDC_COOP);
340 team = (CButton *)GetDlgItem(IDC_TEAMVTEAM);
341 dogfight = (CButton *)GetDlgItem(IDC_DOGFIGHT);
343 m_mission_title_orig = m_mission_title = _T(The_mission.name);
344 m_designer_name_orig = m_designer_name = _T(The_mission.author);
345 m_created = _T(The_mission.created);
346 m_modified = _T(The_mission.modified);
347 m_mission_notes_orig = m_mission_notes = convert_multiline_string(The_mission.notes);
348 m_mission_desc_orig = m_mission_desc = convert_multiline_string(The_mission.mission_desc);
349 m_red_alert = The_mission.red_alert;
350 m_scramble = The_mission.scramble;
351 m_disallow_support = The_mission.disallow_support;
352 m_no_promotion = (The_mission.flags & MISSION_FLAG_NO_PROMOTION) ? 1 : 0;
353 m_no_builtin_msgs = (The_mission.flags & MISSION_FLAG_NO_BUILTIN_MSGS) ? 1 : 0;
354 m_no_traitor = (The_mission.flags & MISSION_FLAG_NO_TRAITOR) ? 1 : 0;
355 CDialog::OnInitDialog();
357 box = (CComboBox *) GetDlgItem(IDC_MUSIC);
358 box->AddString("None");
359 for (i=0; i<Num_soundtracks; i++){
360 box->AddString(Soundtracks[i].name);
364 if(strlen(The_mission.squad_name) > 0){
365 m_squad_name = _T(The_mission.squad_name);
366 m_squad_filename = _T(The_mission.squad_filename);
368 m_squad_name = _T(NO_SQUAD);
369 m_squad_filename = _T("");
372 m_type = The_mission.game_type;
373 m_music = Current_soundtrack_num + 1;
374 m_full_war = Mission_all_attack;
376 // set up the game type checkboxes accoring to m_type
377 if ( m_type & MISSION_TYPE_SINGLE ){
378 ((CButton *) GetDlgItem(IDC_SINGLE))->SetCheck(1);
381 // for multiplayer -- be sure to assign a default type if not already assigned.
382 if ( m_type & MISSION_TYPE_MULTI ){
383 ((CButton *) GetDlgItem(IDC_MULTI))->SetCheck(1);
386 if ( m_type & MISSION_TYPE_TRAINING ){
387 ((CButton *) GetDlgItem(IDC_TRAINING))->SetCheck(1);
390 // we need to set one of these three multiplayer modes so interface looks correct
391 if ( !(m_type & (MISSION_TYPE_MULTI_COOP | MISSION_TYPE_MULTI_DOGFIGHT | MISSION_TYPE_MULTI_TEAMS)) ){
392 m_type |= MISSION_TYPE_MULTI_COOP;
395 if ( m_type & MISSION_TYPE_MULTI_COOP ){
397 } else if ( m_type & MISSION_TYPE_MULTI_TEAMS ){
399 } else if ( m_type & MISSION_TYPE_MULTI_DOGFIGHT ){
400 dogfight->SetCheck(1);
402 Int3(); // get allender -- multiplayer mode not set!!!
405 m_respawn_spin.SetRange(0, 99);
406 m_num_respawns = The_mission.num_respawns;
410 theApp.init_window(&Mission_notes_wnd_data, this);
414 void CMissionNotesDlg::OnClose()
418 if (query_modified()) {
419 z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
433 // when training button is set, we need to disable all other buttons
434 void CMissionNotesDlg::OnTraining()
440 void CMissionNotesDlg::OnMulti()
446 void CMissionNotesDlg::OnSingle()
452 void CMissionNotesDlg::set_types()
456 // when training is checked, no other type is active
457 if (((CButton *) GetDlgItem(IDC_MULTI))->GetCheck() == 1){
461 coop->EnableWindow(enable);
462 team->EnableWindow(enable);
463 dogfight->EnableWindow(enable);
464 GetDlgItem(IDC_RESPAWNS)->EnableWindow(enable);
465 GetDlgItem(IDC_RESPAWN_SPIN)->EnableWindow(enable);
468 void CMissionNotesDlg::OnSquadLogo()
470 CString pcx_filename;
473 // get list of squad images
474 z = cfile_push_chdir(CF_TYPE_SQUAD_IMAGES_MAIN);
475 CFileDialog dlg(TRUE, "pcx", pcx_filename, OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "Pcx Files (*.pcx)|*.pcx");
477 // if we have a result
478 if (dlg.DoModal() == IDOK) {
479 m_squad_filename = dlg.GetFileName();
481 m_squad_filename = _T("");