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/BriefingEditorDlg.cpp $
15 * Briefing editor dialog box class.
18 * Revision 1.3 2002/06/09 04:41:16 relnev
19 * added copyright header
21 * Revision 1.2 2002/05/07 03:16:43 theoddone33
22 * The Great Newline Fix
24 * Revision 1.1.1.1 2002/05/03 03:28:08 root
28 * 9 7/19/99 3:01p Dave
29 * Fixed icons. Added single transport icon.
31 * 8 7/18/99 5:19p Dave
32 * Jump node icon. Fixed debris fogging. Framerate warning stuff.
34 * 7 7/09/99 5:54p Dave
35 * Seperated cruiser types into individual types. Added tons of new
36 * briefing icons. Campaign screen.
38 * 6 5/20/99 1:46p Andsager
39 * Add briefing view copy and paste between stages
41 * 5 4/23/99 12:01p Johnson
44 * 4 11/30/98 5:32p Dave
45 * Fixed up Fred support for software mode.
47 * 3 10/16/98 4:28p Andsager
50 * 2 10/07/98 6:28p Dave
51 * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
52 * Fred. Globalized mission and campaign file extensions. Removed Silent
53 * Threat specific code.
55 * 1 10/07/98 3:02p Dave
57 * 1 10/07/98 3:00p Dave
59 * 63 5/21/98 4:20p Dave
60 * Fixed bug with briefing editor when no current stage selected.
62 * 62 5/21/98 12:58a Hoffoss
63 * Fixed warnings optimized build turned up.
65 * 61 5/14/98 4:47p Hoffoss
66 * Made it so when you switch to a new team's debriefing (via menu), it
67 * updates the camera position to what it should be for new briefing
70 * 60 4/30/98 8:23p John
71 * Fixed some bugs with Fred caused by my new cfile code.
73 * 59 4/22/98 9:56a Sandeep
75 * 58 4/20/98 4:40p Hoffoss
76 * Added a button to 4 editors to play the chosen wave file.
78 * 57 4/16/98 2:49p Johnson
79 * Fixed initialization for new icons in briefing.
81 * 56 4/07/98 6:32p Dave
82 * Fixed function I forget to change back.
84 * 55 4/07/98 6:27p Dave
85 * Implemented a more boiler-plate solution to the multiple team briefing
86 * problem in this editor.
88 * 54 4/07/98 4:51p Dave
89 * (Hoffoss) Fixed a boat load of bugs caused by the new change to
90 * multiple briefings. Allender's code changed to support this in the
91 * briefing editor wasn't quite correct.
93 * 53 4/06/98 5:37p Hoffoss
94 * Added sexp tree support to briefings in Fred.
96 * 52 4/06/98 10:43a John
97 * Fixed bugs with inserting/deleting stages
99 * 51 4/03/98 12:39p Hoffoss
100 * Changed starting directory for browse buttons in several editors.
102 * 50 4/03/98 11:34a John
103 * Fixed the stuff I broke in Fred from the new breifing
105 * 49 3/26/98 6:40p Lawrance
106 * Don't store icon text for briefings
108 * 48 3/21/98 7:36p Lawrance
109 * Move jump nodes to own lib.
111 * 47 3/19/98 4:24p Hoffoss
112 * Added remaining support for command brief screen (ANI and WAVE file
115 * 46 3/17/98 2:00p Hoffoss
116 * Added ability to make an icon from a jump node in briefing editor.
118 * 45 2/18/98 6:44p Hoffoss
119 * Added support for lines between icons in briefings for Fred.
121 * 44 2/09/98 9:25p Allender
122 * team v team support. multiple pools and breifings
124 * 43 2/04/98 4:31p Allender
125 * support for multiple briefings and debriefings. Changes to mission
126 * type (now a bitfield). Bitfield defs for multiplayer modes
128 * 42 1/28/98 7:19p Lawrance
129 * Get fading/highlighting animations working
131 * 41 12/28/97 5:52p Lawrance
132 * Add support for debriefing success/fail music.
134 * 40 11/04/97 4:33p Hoffoss
135 * Made saving keep the current briefing state intact.
137 * 39 11/04/97 11:31a Duncan
138 * Made make icon button gray if at max icons already.
140 * 38 11/03/97 4:07p Jasen
141 * Fixed bug in briefing editor caused by changes in TEAM_* defines in the
142 * past and whoever made these changes failed to update this editor along
145 * 37 10/19/97 11:32p Hoffoss
146 * Added support for briefing cuts in Fred.
148 * 36 10/12/97 11:23p Mike
149 * About ten fixes/changes in the docking system.
150 * Also, renamed SIF_REARM_REPAIR to SIF_SUPPORT.
152 * 35 9/30/97 5:56p Hoffoss
153 * Added music selection combo boxes to Fred.
159 #include <mmsystem.h>
161 #include "briefingeditordlg.h"
163 #include "missionbriefcommon.h"
164 #include "missionparse.h"
165 #include "fredrender.h"
166 #include "management.h"
167 #include "linklist.h"
170 #include "eventmusic.h"
171 #include "starfield.h"
172 #include "jumpnode.h"
176 #define new DEBUG_NEW
178 static char THIS_FILE[] = __FILE__;
182 #define NAVBUOY_NAME "Terran NavBuoy"
184 static int Max_icons_for_lines;
186 /////////////////////////////////////////////////////////////////////////////
187 // briefing_editor_dlg dialog
189 briefing_editor_dlg::briefing_editor_dlg(CWnd* pParent /*=NULL*/)
190 : CDialog(briefing_editor_dlg::IDD, pParent)
194 // figure out max icons we can have with lines to each other less than max allowed lines.
195 // Basically, # lines = (# icons - 1) factorial
196 Max_icons_for_lines = 0;
198 i = ++Max_icons_for_lines + 1;
203 } while (z < MAX_BRIEF_STAGE_LINES);
205 //{{AFX_DATA_INIT(briefing_editor_dlg)
208 m_icon_label = _T("");
209 m_stage_title = _T("");
213 m_icon_text = _T("");
216 m_change_local = FALSE;
218 m_briefing_music = -1;
221 m_current_briefing = -1;
224 m_last_stage = m_cur_icon = m_last_icon = -1;
225 m_tree.link_modified(&modified); // provide way to indicate trees are modified in dialog
227 // copy view initialization
231 void briefing_editor_dlg::DoDataExchange(CDataExchange* pDX)
233 CDialog::DoDataExchange(pDX);
234 //{{AFX_DATA_MAP(briefing_editor_dlg)
235 DDX_Control(pDX, IDC_TREE, m_tree);
236 DDX_Control(pDX, IDC_LINES, m_lines);
237 DDX_Check(pDX, IDC_HILIGHT, m_hilight);
238 DDX_CBIndex(pDX, IDC_ICON_IMAGE, m_icon_image);
239 DDX_Text(pDX, IDC_ICON_LABEL, m_icon_label);
240 DDX_Text(pDX, IDC_STAGE_TITLE, m_stage_title);
241 DDX_Text(pDX, IDC_TEXT, m_text);
242 DDX_Text(pDX, IDC_TIME, m_time);
243 DDX_Text(pDX, IDC_VOICE, m_voice);
244 DDX_Text(pDX, IDC_ICON_TEXT, m_icon_text);
245 DDX_CBIndex(pDX, IDC_TEAM, m_icon_team);
246 DDX_CBIndex(pDX, IDC_SHIP_TYPE, m_ship_type);
247 DDX_Check(pDX, IDC_LOCAL, m_change_local);
248 DDX_Text(pDX, IDC_ID, m_id);
249 DDX_CBIndex(pDX, IDC_BRIEFING_MUSIC, m_briefing_music);
250 DDX_Check(pDX, IDC_CUT_NEXT, m_cut_next);
251 DDX_Check(pDX, IDC_CUT_PREV, m_cut_prev);
254 DDV_MaxChars(pDX, m_text, MAX_BRIEF_LEN - 1);
255 DDV_MaxChars(pDX, m_voice, MAX_FILENAME_LEN - 1);
256 DDV_MaxChars(pDX, m_icon_label, MAX_LABEL_LEN - 1);
257 DDV_MaxChars(pDX, m_icon_text, MAX_ICON_TEXT_LEN - 1);
260 BEGIN_MESSAGE_MAP(briefing_editor_dlg, CDialog)
261 //{{AFX_MSG_MAP(briefing_editor_dlg)
263 ON_BN_CLICKED(IDC_NEXT, OnNext)
264 ON_BN_CLICKED(IDC_PREV, OnPrev)
265 ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
266 ON_BN_CLICKED(IDC_ADD_STAGE, OnAddStage)
267 ON_BN_CLICKED(IDC_DELETE_STAGE, OnDeleteStage)
268 ON_BN_CLICKED(IDC_INSERT_STAGE, OnInsertStage)
269 ON_BN_CLICKED(IDC_MAKE_ICON, OnMakeIcon)
270 ON_BN_CLICKED(IDC_DELETE_ICON, OnDeleteIcon)
271 ON_BN_CLICKED(IDC_GOTO_VIEW, OnGotoView)
272 ON_BN_CLICKED(IDC_SAVE_VIEW, OnSaveView)
273 ON_CBN_SELCHANGE(IDC_ICON_IMAGE, OnSelchangeIconImage)
274 ON_CBN_SELCHANGE(IDC_TEAM, OnSelchangeTeam)
275 ON_BN_CLICKED(IDC_PROPAGATE_ICONS, OnPropagateIcons)
277 ON_BN_CLICKED(IDC_LINES, OnLines)
278 ON_NOTIFY(NM_RCLICK, IDC_TREE, OnRclickTree)
279 ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_TREE, OnBeginlabeleditTree)
280 ON_NOTIFY(TVN_ENDLABELEDIT, IDC_TREE, OnEndlabeleditTree)
281 ON_BN_CLICKED(IDC_PLAY, OnPlay)
282 ON_BN_CLICKED(IDC_COPY_VIEW, OnCopyView)
283 ON_BN_CLICKED(IDC_PASTE_VIEW, OnPasteView)
287 /////////////////////////////////////////////////////////////////////////////
288 // briefing_editor_dlg message handlers
290 void briefing_editor_dlg::OnInitMenu(CMenu* pMenu)
295 // disable any items we should disable
296 m = pMenu->GetSubMenu(0);
298 // uncheck all menu items
299 for (i=0; i<Num_teams; i++)
300 m->CheckMenuItem(i, MF_BYPOSITION | MF_UNCHECKED);
302 for (i=Num_teams; i<MAX_TEAMS; i++)
303 m->EnableMenuItem(i, MF_BYPOSITION | MF_GRAYED);
305 // put a check next to the currently selected item
306 m->CheckMenuItem(m_current_briefing, MF_BYPOSITION | MF_CHECKED );
308 CDialog::OnInitMenu(pMenu);
311 void briefing_editor_dlg::create()
316 CDialog::Create(IDD);
317 theApp.init_window(&Briefing_wnd_data, this);
318 box = (CComboBox *) GetDlgItem(IDC_ICON_IMAGE);
319 for (i=0; i<MAX_BRIEF_ICONS; i++)
320 box->AddString(Icon_names[i]);
322 box = (CComboBox *) GetDlgItem(IDC_TEAM);
323 for (i=0; i<Num_team_names; i++)
324 box->AddString(Team_names[i]);
326 box = (CComboBox *) GetDlgItem(IDC_SHIP_TYPE);
327 for (i=0; i<Num_ship_types; i++)
328 box->AddString(Ship_info[i].name);
330 box = (CComboBox *) GetDlgItem(IDC_BRIEFING_MUSIC);
331 box->AddString("None");
332 for (i=0; i<Num_music_files; i++)
333 box->AddString(Spooled_music[i].name);
335 m_play_bm.LoadBitmap(IDB_PLAY);
336 ((CButton *) GetDlgItem(IDC_PLAY)) -> SetBitmap(m_play_bm);
338 m_current_briefing = 0;
339 Briefing = &Briefings[m_current_briefing];
340 m_briefing_music = Mission_music[SCORE_BRIEFING] + 1;
347 void briefing_editor_dlg::focus_sexp(int select_sexp_node)
351 n = m_tree.select_sexp_node = select_sexp_node;
353 for (i=0; i<Briefing->num_stages; i++)
354 if (query_node_in_sexp(n, Briefing->stages[i].formula))
357 if (i < Briefing->num_stages) {
360 GetDlgItem(IDC_TREE) -> SetFocus();
361 m_tree.hilite_item(m_tree.select_sexp_node);
366 void briefing_editor_dlg::OnOK()
370 void briefing_editor_dlg::OnCancel()
375 void briefing_editor_dlg::OnClose()
377 int bs, i, j, s, t, dup = 0;
378 briefing_editor_dlg *ptr;
384 for ( bs = 0; bs < Num_teams; bs++ ) {
385 for (s=0; s<Briefing[bs].num_stages; s++) {
386 sp = &Briefing[bs].stages[s];
388 for (i=0; i<t-1; i++)
389 for (j=i+1; j<t; j++) {
390 if ((sp->icons[i].id >= 0) && (sp->icons[i].id == sp->icons[j].id))
397 MessageBox("You have duplicate icons names. You should resolve these.", "Warning");
399 theApp.record_window_data(&Briefing_wnd_data, this);
400 ptr = Briefing_dialog;
401 Briefing_dialog = NULL;
405 void briefing_editor_dlg::reset_editor()
411 // some kind of hackish code to get around the problem if saving (which implicitly loads,
412 // which implicitly clears all mission info) not affecting the editor's state at save.
413 void briefing_editor_dlg::save_editor_state()
415 stage_saved = m_cur_stage;
416 icon_saved = m_cur_icon;
419 void briefing_editor_dlg::restore_editor_state()
421 m_cur_stage = stage_saved;
422 m_cur_icon = icon_saved;
425 void briefing_editor_dlg::update_data(int update)
427 char buf[MAX_LABEL_LEN], buf2[MAX_ICON_TEXT_LEN], buf3[MAX_BRIEF_LEN];
428 int i, j, l, lines, count, enable = TRUE, valid = 0, invalid = 0;
430 brief_stage *ptr = NULL;
435 // save off current data before we update over it with new briefing stage/team stuff
436 Briefing = save_briefing;
438 Mission_music[SCORE_BRIEFING] = m_briefing_music - 1;
439 if (m_last_stage >= 0) {
440 ptr = &Briefing->stages[m_last_stage];
441 deconvert_multiline_string(buf3, m_text, MAX_BRIEF_LEN);
442 if (stricmp(ptr->new_text, buf3))
445 strcpy(ptr->new_text, buf3);
446 MODIFY(ptr->camera_time, atoi(m_time));
447 string_copy(ptr->voice, m_voice, MAX_FILENAME_LEN, 1);
450 i |= BS_BACKWARD_CUT;
452 i &= ~BS_BACKWARD_CUT;
457 i &= ~BS_FORWARD_CUT;
459 MODIFY(ptr->flags, i);
460 ptr->formula = m_tree.save_tree();
461 switch (m_lines.GetCheck()) {
463 // add lines between every pair of 2 marked icons if there isn't one already.
464 for (i=0; i<ptr->num_icons - 1; i++)
465 for (j=i+1; j<ptr->num_icons; j++) {
466 if ( icon_marked[i] && icon_marked[j] ) {
467 for (l=0; l<ptr->num_lines; l++)
468 if ( ((ptr->lines[l].start_icon == i) && (ptr->lines[l].end_icon == j)) || ((ptr->lines[l].start_icon == j) && (ptr->lines[l].end_icon == i)) )
471 if ((l == ptr->num_lines) && (l < MAX_BRIEF_STAGE_LINES)) {
472 ptr->lines[l].start_icon = i;
473 ptr->lines[l].end_icon = j;
482 // remove all existing lines between any 2 marked icons
485 if ( icon_marked[ptr->lines[i].start_icon] && icon_marked[ptr->lines[i].end_icon] ) {
487 for (l=i; l<ptr->num_lines; l++)
488 ptr->lines[l] = ptr->lines[l + 1];
494 if (m_last_icon >= 0) {
495 valid = (m_id != ptr->icons[m_last_icon].id);
497 if (valid && !m_change_local) {
498 for (i=m_last_stage+1; i<Briefing->num_stages; i++) {
499 if (find_icon(m_id, i) >= 0) {
503 sprintf(msg, "Icon ID #%d is already used in a later stage. You can only\n"
504 "change to that ID locally. Icon ID has been reset back to %d", m_id, ptr->icons[m_last_icon].id);
506 m_id = ptr->icons[m_last_icon].id;
513 for (i=0; i<ptr->num_icons; i++)
514 if ((i != m_last_icon) && (ptr->icons[i].id == m_id)) {
517 sprintf(msg, "Icon ID #%d is already used in this stage. Icon ID has been reset back to %d",
518 m_id, ptr->icons[m_last_icon].id);
520 m_id = ptr->icons[m_last_icon].id;
525 if (valid && !m_change_local) {
527 reset_icon_loop(m_last_stage);
528 while (get_next_icon(ptr->icons[m_last_icon].id))
533 ptr->icons[m_last_icon].id = m_id;
534 string_copy(buf, m_icon_label, MAX_LABEL_LEN);
535 if (stricmp(ptr->icons[m_last_icon].label, buf) && !m_change_local) {
537 reset_icon_loop(m_last_stage);
538 while (get_next_icon(m_id))
539 strcpy(iconp->label, buf);
542 strcpy(ptr->icons[m_last_icon].label, buf);
544 ptr->icons[m_last_icon].flags |= BI_HIGHLIGHT;
546 ptr->icons[m_last_icon].flags &= ~BI_HIGHLIGHT;
548 if ((ptr->icons[m_last_icon].type != m_icon_image) && !m_change_local) {
550 reset_icon_loop(m_last_stage);
551 while (get_next_icon(m_id))
552 iconp->type = m_icon_image;
555 ptr->icons[m_last_icon].type = m_icon_image;
556 if ((ptr->icons[m_last_icon].team != (1 << m_icon_team)) && !m_change_local) {
558 reset_icon_loop(m_last_stage);
559 while (get_next_icon(m_id))
560 iconp->team = (1 << m_icon_team);
563 ptr->icons[m_last_icon].team = (1 << m_icon_team);
564 if ((ptr->icons[m_last_icon].ship_class != m_ship_type) && !m_change_local) {
566 reset_icon_loop(m_last_stage);
567 while (get_next_icon(m_id))
568 iconp->ship_class = m_ship_type;
571 MODIFY(ptr->icons[m_last_icon].ship_class, m_ship_type);
572 deconvert_multiline_string(buf2, m_icon_text, MAX_ICON_TEXT_LEN);
574 if (stricmp(ptr->icons[m_last_icon].text, buf2) && !m_change_local) {
576 reset_icon_loop(m_last_stage);
577 while (get_next_icon(m_id))
578 strcpy(iconp->text, buf2);
581 strcpy(ptr->icons[m_last_icon].text, buf2);
586 if (!::IsWindow(m_hWnd))
589 // set briefing pointer to correct team
590 Briefing = &Briefings[m_current_briefing];
592 if ((m_cur_stage >= 0) && (m_cur_stage < Briefing->num_stages)) {
593 ptr = &Briefing->stages[m_cur_stage];
594 m_stage_title.Format("Stage %d of %d", m_cur_stage + 1, Briefing->num_stages);
595 m_text = convert_multiline_string(ptr->new_text);
596 m_time.Format("%d", ptr->camera_time);
597 m_voice = ptr->voice;
598 m_cut_prev = (ptr->flags & BS_BACKWARD_CUT) ? 1 : 0;
599 m_cut_next = (ptr->flags & BS_FORWARD_CUT) ? 1 : 0;
600 m_tree.load_tree(ptr->formula);
603 m_stage_title = _T("No stages");
607 m_cut_prev = m_cut_next = 0;
613 if (m_cur_stage == Briefing->num_stages - 1)
614 GetDlgItem(IDC_NEXT) -> EnableWindow(FALSE);
616 GetDlgItem(IDC_NEXT) -> EnableWindow(enable);
619 GetDlgItem(IDC_PREV) -> EnableWindow(enable);
621 GetDlgItem(IDC_PREV) -> EnableWindow(FALSE);
623 if (Briefing->num_stages >= MAX_BRIEF_STAGES)
624 GetDlgItem(IDC_ADD_STAGE) -> EnableWindow(FALSE);
626 GetDlgItem(IDC_ADD_STAGE) -> EnableWindow(TRUE);
628 if (Briefing->num_stages) {
629 GetDlgItem(IDC_DELETE_STAGE) -> EnableWindow(enable);
630 GetDlgItem(IDC_INSERT_STAGE) -> EnableWindow(enable);
632 GetDlgItem(IDC_DELETE_STAGE) -> EnableWindow(FALSE);
633 GetDlgItem(IDC_INSERT_STAGE) -> EnableWindow(FALSE);
636 GetDlgItem(IDC_TIME) -> EnableWindow(enable);
637 GetDlgItem(IDC_VOICE) -> EnableWindow(enable);
638 GetDlgItem(IDC_BROWSE) -> EnableWindow(enable);
639 GetDlgItem(IDC_TEXT) -> EnableWindow(enable);
640 GetDlgItem(IDC_SAVE_VIEW) -> EnableWindow(enable);
641 GetDlgItem(IDC_GOTO_VIEW) -> EnableWindow(enable);
642 GetDlgItem(IDC_CUT_PREV) -> EnableWindow(enable);
643 GetDlgItem(IDC_CUT_NEXT) -> EnableWindow(enable);
644 GetDlgItem(IDC_TREE) -> EnableWindow(enable);
645 GetDlgItem(IDC_PLAY) -> EnableWindow(enable);
647 if ((m_cur_stage >= 0) && (m_cur_icon >= 0) && (m_cur_icon < ptr->num_icons)) {
648 m_hilight = (ptr->icons[m_cur_icon].flags & BI_HIGHLIGHT)?1:0;
649 m_icon_image = ptr->icons[m_cur_icon].type;
650 m_icon_team = bitmask_2_bitnum(ptr->icons[m_cur_icon].team);
651 m_icon_label = ptr->icons[m_cur_icon].label;
652 m_ship_type = ptr->icons[m_cur_icon].ship_class;
653 // m_icon_text = convert_multiline_string(ptr->icons[m_cur_icon].text);
654 m_id = ptr->icons[m_cur_icon].id;
662 m_icon_label = _T("");
668 GetDlgItem(IDC_ICON_TEXT) -> EnableWindow(enable);
669 GetDlgItem(IDC_ICON_LABEL) -> EnableWindow(enable);
670 GetDlgItem(IDC_ICON_IMAGE) -> EnableWindow(enable);
671 GetDlgItem(IDC_SHIP_TYPE) -> EnableWindow(enable);
672 GetDlgItem(IDC_HILIGHT) -> EnableWindow(enable);
673 GetDlgItem(IDC_TEAM) -> EnableWindow(enable);
674 GetDlgItem(IDC_ID) -> EnableWindow(enable);
675 GetDlgItem(IDC_DELETE_ICON) -> EnableWindow(enable);
678 objp = GET_FIRST(&obj_used_list);
679 while (objp != END_OF_LIST(&obj_used_list)) {
680 if (objp->flags & OF_MARKED) {
681 if ((objp->type == OBJ_SHIP) || (objp->type == OBJ_START) || (objp->type == OBJ_WAYPOINT) || (objp->type == OBJ_JUMP_NODE))
687 objp = GET_NEXT(objp);
690 if (m_cur_stage >= 0)
691 ptr = &Briefing->stages[m_cur_stage];
693 if (valid && !invalid && (m_cur_stage >= 0) && (ptr->num_icons < MAX_STAGE_ICONS))
694 GetDlgItem(IDC_MAKE_ICON) -> EnableWindow(TRUE);
696 GetDlgItem(IDC_MAKE_ICON) -> EnableWindow(FALSE);
698 if (m_cur_stage >= 0)
699 for (i=0; i<ptr->num_icons; i++)
703 objp = GET_FIRST(&obj_used_list);
704 while (objp != END_OF_LIST(&obj_used_list)) {
705 if (objp->flags & OF_MARKED) {
706 if (objp->type == OBJ_POINT) {
708 icon_marked[objp->instance] = 1;
714 objp = GET_NEXT(objp);
717 if (valid && !invalid && (m_cur_stage >= 0))
718 GetDlgItem(IDC_PROPAGATE_ICONS) -> EnableWindow(TRUE);
720 GetDlgItem(IDC_PROPAGATE_ICONS) -> EnableWindow(FALSE);
723 lines = 1; // default lines checkbox to checked
725 if (m_cur_stage >= 0) {
726 for (i=0; i<ptr->num_lines; i++)
729 // go through and locate all lines between marked icons
730 for (i=0; i<ptr->num_icons - 1; i++)
731 for (j=i+1; j<ptr->num_icons; j++) {
732 if ( icon_marked[i] && icon_marked[j] ) {
733 for (l=0; l<ptr->num_lines; l++)
734 if ( ((ptr->lines[l].start_icon == i) && (ptr->lines[l].end_icon == j)) || ((ptr->lines[l].start_icon == j) && (ptr->lines[l].end_icon == i)) ) {
736 count++; // track number of marked lines (lines between 2 icons that are both marked)
740 // at least 1 line missing between 2 marked icons, so use mixed state
741 if (l == ptr->num_lines)
747 // not even 1 line between any 2 marked icons? Set checkbox to unchecked.
752 if (m_cur_stage >= 0){
753 i = calc_num_lines_for_icons(valid) + ptr->num_lines - count;
756 if ((valid > 1) && !invalid && (m_cur_stage >= 0) && (i <= MAX_BRIEF_STAGE_LINES))
757 GetDlgItem(IDC_LINES) -> EnableWindow(TRUE);
759 GetDlgItem(IDC_LINES) -> EnableWindow(FALSE);
761 m_lines.SetCheck(lines);
764 if ((m_last_stage != m_cur_stage) || (Briefing != save_briefing)) {
765 if (m_last_stage >= 0) {
766 for (i=0; i<save_briefing->stages[m_last_stage].num_icons; i++) {
767 // save positions of all icons, in case they have moved
768 save_briefing->stages[m_last_stage].icons[i].pos = Objects[icon_obj[i]].pos;
769 // release objects being used by last stage
770 obj_delete(icon_obj[i]);
774 if (m_cur_stage >= 0) {
775 for (i=0; i<ptr->num_icons; i++) {
776 // create an object for each icon for display/manipulation purposes
777 icon_obj[i] = obj_create(OBJ_POINT, -1, i, NULL, &ptr->icons[i].pos, 0.0f, OF_RENDERS);
780 obj_merge_created_list();
783 m_last_stage = m_cur_stage;
786 m_last_icon = m_cur_icon;
788 save_briefing = Briefing;
791 // Given a number of icons, figure out how many lines would be required to connect each one
792 // with all of the others.
794 int briefing_editor_dlg::calc_num_lines_for_icons(int num)
801 // Basically, this is # lines = (# icons - 1) factorial
808 void briefing_editor_dlg::OnNext()
816 void briefing_editor_dlg::OnPrev()
824 void briefing_editor_dlg::OnBrowse()
831 if (The_mission.game_type & MISSION_TYPE_TRAINING)
832 z = cfile_push_chdir(CF_TYPE_VOICE_TRAINING);
834 z = cfile_push_chdir(CF_TYPE_VOICE_BRIEFINGS);
836 CFileDialog dlg(TRUE, "wav", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
837 "Wave Files (*.wav)|*.wav||");
839 if (dlg.DoModal() == IDOK) {
840 m_voice = dlg.GetFileName();
848 void briefing_editor_dlg::OnAddStage()
852 if (Briefing->num_stages >= MAX_BRIEF_STAGES)
855 m_cur_stage = i = Briefing->num_stages++;
856 copy_stage(i - 1, i);
860 void briefing_editor_dlg::OnDeleteStage()
867 SDL_assert(Briefing->num_stages);
871 for (i=z+1; i<Briefing->num_stages; i++) {
875 Briefing->num_stages--;
877 if (m_cur_stage >= Briefing->num_stages)
878 m_cur_stage = Briefing->num_stages - 1;
883 void briefing_editor_dlg::draw_icon(object *objp)
888 brief_render_icon(m_cur_stage, objp->instance, 1.0f/30.0f, objp->flags & OF_MARKED,
889 (float) True_rw / BRIEF_GRID_W, (float) True_rh / BRIEF_GRID_H);
892 void briefing_editor_dlg::batch_render()
900 num_lines = Briefing->stages[m_cur_stage].num_lines;
901 for (i=0; i<num_lines; i++)
902 brief_render_icon_line(m_cur_stage, i);
905 void briefing_editor_dlg::icon_select(int num)
911 void briefing_editor_dlg::OnInsertStage()
915 if (Briefing->num_stages >= MAX_BRIEF_STAGES)
918 if (!Briefing->num_stages) {
926 for (i=Briefing->num_stages; i>z; i--) {
930 Briefing->num_stages++;
931 copy_stage(z, z + 1);
936 void briefing_editor_dlg::copy_stage(int from, int to)
938 if ((from < 0) || (from >= Briefing->num_stages)) {
939 strcpy(Briefing->stages[to].new_text, "<Text here>");
940 strcpy(Briefing->stages[to].voice, "none.wav");
941 Briefing->stages[to].camera_pos = view_pos;
942 Briefing->stages[to].camera_orient = view_orient;
943 Briefing->stages[to].camera_time = 500;
944 Briefing->stages[to].num_icons = 0;
945 Briefing->stages[to].formula = Locked_sexp_true;
949 // Copy all the data in the stage structure.
950 strcpy( Briefing->stages[to].new_text, Briefing->stages[from].new_text );
951 strcpy( Briefing->stages[to].voice, Briefing->stages[from].voice );
952 Briefing->stages[to].camera_pos = Briefing->stages[from].camera_pos;
953 Briefing->stages[to].camera_orient = Briefing->stages[from].camera_orient;
954 Briefing->stages[to].camera_time = Briefing->stages[from].camera_time;
955 Briefing->stages[to].flags = Briefing->stages[from].flags;
956 Briefing->stages[to].num_icons = Briefing->stages[from].num_icons;
957 Briefing->stages[to].num_lines = Briefing->stages[from].num_lines;
958 Briefing->stages[to].formula = Briefing->stages[from].formula;
960 memmove( Briefing->stages[to].icons, Briefing->stages[from].icons, sizeof(brief_icon)*MAX_STAGE_ICONS );
961 memmove( Briefing->stages[to].lines, Briefing->stages[from].lines, sizeof(brief_line)*MAX_BRIEF_STAGE_LINES );
964 void briefing_editor_dlg::update_positions()
972 for (i=0; i<Briefing->stages[m_cur_stage].num_icons; i++) {
973 v1 = Briefing->stages[m_cur_stage].icons[i].pos;
974 v2 = Objects[icon_obj[i]].pos;
975 if ((v1.x != v2.x) || (v1.y != v2.y) || (v1.z != v2.z)) {
976 Briefing->stages[m_cur_stage].icons[i].pos = Objects[icon_obj[i]].pos;
977 if (!m_change_local) // propagate changes through rest of stages..
978 for (s=m_cur_stage+1; s<Briefing->num_stages; s++) {
979 z = find_icon(Briefing->stages[m_cur_stage].icons[i].id, s);
981 Briefing->stages[s].icons[z].pos = Objects[icon_obj[i]].pos;
987 void briefing_editor_dlg::OnMakeIcon()
990 int z, len, team, ship, waypoint, jump_node, count = -1;
991 int cargo = 0, cargo_count = 0, freighter_count = 0;
993 vector min, max, pos;
996 if (Briefing->stages[m_cur_stage].num_icons >= MAX_STAGE_ICONS)
999 m_cur_icon = Briefing->stages[m_cur_stage].num_icons++;
1000 iconp = &Briefing->stages[m_cur_stage].icons[m_cur_icon];
1001 ship = waypoint = jump_node = -1;
1002 team = TEAM_FRIENDLY;
1004 vm_vec_make(&min, 9e19f, 9e19f, 9e19f);
1005 vm_vec_make(&max, -9e19f, -9e19f, -9e19f);
1006 ptr = GET_FIRST(&obj_used_list);
1007 while (ptr != END_OF_LIST(&obj_used_list)) {
1008 if (ptr->flags & OF_MARKED) {
1009 if (ptr->pos.x < min.x)
1011 if (ptr->pos.x > max.x)
1013 if (ptr->pos.y < min.y)
1015 if (ptr->pos.y > max.y)
1017 if (ptr->pos.z < min.z)
1019 if (ptr->pos.z > max.z)
1022 switch (ptr->type) {
1025 ship = ptr->instance;
1029 waypoint = ptr->instance;
1033 jump_node = ptr->instance;
1041 team = Ships[ship].team;
1043 z = ship_query_general_type(ship);
1044 if (z == SHIP_TYPE_CARGO)
1047 if (z == SHIP_TYPE_FREIGHTER)
1049 z = Ai_info[Ships[ship].ai_index].dock_objnum;
1050 if (z) { // docked with anything?
1051 if ((Objects[z].flags & OF_MARKED) && (Objects[z].type == OBJ_SHIP)) {
1052 if (ship_query_general_type(Objects[z].instance) == SHIP_TYPE_CARGO)
1062 ptr = GET_NEXT(ptr);
1065 if (cargo_count && cargo_count == freighter_count)
1068 vm_vec_avg(&pos, &min, &max);
1070 name = Ships[ship].ship_name;
1071 else if (waypoint >= 0)
1072 name = Waypoint_lists[waypoint / 65536].name;
1073 else if (jump_node >= 0)
1074 name = Jump_nodes[jump_node].name;
1079 if (len >= MAX_LABEL_LEN - 1)
1080 len = MAX_LABEL_LEN - 1;
1082 strncpy(iconp->label, name, len);
1083 iconp->label[len] = 0;
1084 // iconp->text[0] = 0;
1089 iconp->id = Cur_brief_id++;
1091 iconp->ship_class = Ships[ship].ship_info_index;
1092 switch (Ship_info[Ships[ship].ship_info_index].flags & SIF_ALL_SHIP_TYPES) {
1093 case SIF_KNOSSOS_DEVICE:
1094 iconp->type = ICON_KNOSSOS_DEVICE;
1098 iconp->type = ICON_CORVETTE;
1102 iconp->type = ICON_GAS_MINER;
1106 iconp->type = ICON_SUPERCAP;
1110 iconp->type = ICON_SENTRYGUN;
1114 iconp->type = ICON_AWACS;
1119 iconp->type = (count == 1) ? ICON_FREIGHTER_WITH_CARGO : ICON_FREIGHTER_WING_WITH_CARGO;
1121 iconp->type = count ? ICON_CARGO_WING : ICON_CARGO;
1126 iconp->type = ICON_SUPPORT_SHIP;
1130 iconp->type = count ? ICON_FIGHTER_WING : ICON_FIGHTER;
1134 iconp->type = count ? ICON_BOMBER_WING : ICON_BOMBER;
1139 iconp->type = (count == 1) ? ICON_FREIGHTER_WITH_CARGO : ICON_FREIGHTER_WING_WITH_CARGO;
1141 iconp->type = count ? ICON_FREIGHTER_WING_NO_CARGO : ICON_FREIGHTER_NO_CARGO;
1146 iconp->type = count ? ICON_CRUISER_WING : ICON_CRUISER;
1150 iconp->type = count ? ICON_TRANSPORT_WING : ICON_TRANSPORT;
1155 iconp->type = ICON_CAPITAL;
1159 if (Ships[ship].ship_info_index == ship_info_lookup(NAVBUOY_NAME))
1160 iconp->type = ICON_WAYPOINT;
1162 iconp->type = ICON_ASTEROID_FIELD;
1168 else if(jump_node >= 0){
1169 iconp->ship_class = ship_info_lookup(NAVBUOY_NAME);
1170 iconp->type = ICON_JUMP_NODE;
1174 iconp->ship_class = ship_info_lookup(NAVBUOY_NAME);
1175 iconp->type = ICON_WAYPOINT;
1178 if (!m_change_local){
1179 propagate_icon(m_cur_icon);
1182 icon_obj[m_cur_icon] = obj_create(OBJ_POINT, -1, m_cur_icon, NULL, &pos, 0.0f, OF_RENDERS);
1183 SDL_assert(icon_obj[m_cur_icon] >= 0);
1184 obj_merge_created_list();
1186 set_cur_object_index(icon_obj[m_cur_icon]);
1187 GetDlgItem(IDC_MAKE_ICON) -> EnableWindow(FALSE);
1188 GetDlgItem(IDC_PROPAGATE_ICONS) -> EnableWindow(TRUE);
1192 void briefing_editor_dlg::OnDeleteIcon()
1194 delete_icon(m_cur_icon);
1197 void briefing_editor_dlg::delete_icon(int num)
1207 SDL_assert(m_cur_stage >= 0);
1208 SDL_assert(Briefing->stages[m_cur_stage].num_icons);
1217 obj_delete(icon_obj[num]);
1218 for (i=num+1; i<Briefing->stages[m_cur_stage].num_icons; i++) {
1219 Briefing->stages[m_cur_stage].icons[i-1] = Briefing->stages[m_cur_stage].icons[i];
1220 icon_obj[i-1] = icon_obj[i];
1221 Objects[icon_obj[i-1]].instance = i - 1;
1224 Briefing->stages[m_cur_stage].num_icons--;
1231 void briefing_editor_dlg::OnGotoView()
1233 if (m_cur_stage < 0)
1236 view_pos = Briefing->stages[m_cur_stage].camera_pos;
1237 view_orient = Briefing->stages[m_cur_stage].camera_orient;
1241 void briefing_editor_dlg::OnSaveView()
1243 if (m_cur_stage < 0)
1246 Briefing->stages[m_cur_stage].camera_pos = view_pos;
1247 Briefing->stages[m_cur_stage].camera_orient = view_orient;
1250 void briefing_editor_dlg::OnSelchangeIconImage()
1255 void briefing_editor_dlg::OnSelchangeTeam()
1260 int briefing_editor_dlg::check_mouse_hit(int x, int y)
1265 if (m_cur_stage < 0)
1268 for (i=0; i<Briefing->stages[m_cur_stage].num_icons; i++) {
1269 ptr = &Briefing->stages[m_cur_stage].icons[i];
1270 if ((x > ptr->x) && (x < ptr->x + ptr->w) && (y > ptr->y) && (y < ptr->y + ptr->h)) {
1278 void briefing_editor_dlg::OnPropagateIcons()
1282 ptr = GET_FIRST(&obj_used_list);
1283 while (ptr != END_OF_LIST(&obj_used_list)) {
1284 if ((ptr->type == OBJ_POINT) && (ptr->flags & OF_MARKED)) {
1285 propagate_icon(ptr->instance);
1288 ptr = GET_NEXT(ptr);
1292 void briefing_editor_dlg::propagate_icon(int num)
1296 for (s=m_cur_stage+1; s<Briefing->num_stages; s++) {
1297 i = Briefing->stages[s].num_icons;
1298 if (i >= MAX_STAGE_ICONS)
1301 if (find_icon(Briefing->stages[m_cur_stage].icons[num].id, s) >= 0)
1302 continue; // don't change if icon exists here already.
1304 Briefing->stages[s].icons[i] = Briefing->stages[m_cur_stage].icons[num];
1305 Briefing->stages[s].num_icons++;
1309 int briefing_editor_dlg::find_icon(int id, int stage)
1314 for (i=0; i<Briefing->stages[stage].num_icons; i++)
1315 if (Briefing->stages[stage].icons[i].id == id)
1321 void briefing_editor_dlg::reset_icon_loop(int stage)
1323 stage_loop = stage + 1;
1327 int briefing_editor_dlg::get_next_icon(int id)
1331 if (icon_loop >= Briefing->stages[stage_loop].num_icons) {
1333 if (stage_loop > Briefing->num_stages)
1340 iconp = &Briefing->stages[stage_loop].icons[icon_loop];
1341 if ((id >= 0) && (iconp->id == id))
1346 BOOL briefing_editor_dlg::OnCommand(WPARAM wParam, LPARAM lParam)
1350 // deal with figuring out menu stuff
1351 id = LOWORD(wParam);
1352 if ( (id >= ID_TEAM_1) && (id < ID_TEAM_3) ) {
1353 m_current_briefing = id - ID_TEAM_1;
1355 // put user back at first stage for this team (or no current stage is there are none).
1356 Briefing = &Briefings[m_current_briefing];
1357 if ( Briefing->num_stages > 0 )
1367 return CDialog::OnCommand(wParam, lParam);
1370 void briefing_editor_dlg::OnLines()
1372 if (m_lines.GetCheck() == 1)
1373 m_lines.SetCheck(0);
1375 m_lines.SetCheck(1);
1380 void briefing_editor_dlg::OnRclickTree(NMHDR* pNMHDR, LRESULT* pResult)
1382 m_tree.right_clicked();
1386 void briefing_editor_dlg::OnBeginlabeleditTree(NMHDR* pNMHDR, LRESULT* pResult)
1388 TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
1390 if (m_tree.edit_label(pTVDispInfo->item.hItem) == 1) {
1398 void briefing_editor_dlg::OnEndlabeleditTree(NMHDR* pNMHDR, LRESULT* pResult)
1400 TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
1402 *pResult = m_tree.end_label_edit(pTVDispInfo->item.hItem, pTVDispInfo->item.pszText);
1405 BOOL briefing_editor_dlg::DestroyWindow()
1407 m_play_bm.DeleteObject();
1408 return CDialog::DestroyWindow();
1411 void briefing_editor_dlg::OnPlay()
1413 char path[MAX_PATH_LEN + 1];
1414 GetDlgItem(IDC_VOICE)->GetWindowText(m_voice);
1417 cf_find_file_location((char *) (LPCSTR) m_voice, CF_TYPE_ANY, path, &size, &offset );
1419 PlaySound(path, NULL, SND_ASYNC | SND_FILENAME);
1422 void briefing_editor_dlg::OnCopyView()
1424 // TODO: Add your control notification handler code here
1426 m_copy_view_set = 1;
1427 m_copy_view_pos = view_pos;
1428 m_copy_view_orient = view_orient;
1431 void briefing_editor_dlg::OnPasteView()
1433 // TODO: Add your control notification handler code here
1434 if (m_cur_stage < 0)
1437 if (m_copy_view_set == 0) {
1438 MessageBox("No view set", "Unable to copy view");
1440 Briefing->stages[m_cur_stage].camera_pos = m_copy_view_pos;
1441 Briefing->stages[m_cur_stage].camera_orient = m_copy_view_orient;