FS2_Open
Open source remastering of the Freespace 2 engine
campaigneditordlg.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
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 the
6  * source.
7  *
8 */
9 
10 // CampaignEditorDlg.cpp : implementation file
11 //
12 
13 #include <setjmp.h>
14 #include "stdafx.h"
15 #include "FRED.h"
16 #include "CampaignEditorDlg.h"
17 #include "CampaignTreeView.h"
18 #include "CampaignTreeWnd.h"
19 #include "Management.h"
20 #include "cfile/cfile.h"
21 #include "FREDDoc.h"
22 #include "parse/parselo.h"
23 #include "mission/missiongoals.h"
24 
25 #ifdef _DEBUG
26 #undef THIS_FILE
27 static char THIS_FILE[] = __FILE__;
28 #endif
29 
32 
34 // campaign_editor dialog
35 
36 IMPLEMENT_DYNCREATE(campaign_editor, CFormView)
37 
39 
41  : CFormView(campaign_editor::IDD)
42 {
43  //{{AFX_DATA_INIT(campaign_editor)
44  m_name = _T("");
45  m_type = -1;
46  m_num_players = _T("");
47  m_desc = _T("");
48  m_branch_desc = _T("");
49  m_branch_brief_anim = _T("");
50  m_branch_brief_sound = _T("");
51  m_custom_tech_db = FALSE;
52  //}}AFX_DATA_INIT
53 
54  m_tree.m_mode = MODE_CAMPAIGN;
55  m_num_links = 0;
56  m_tree.link_modified(&Campaign_modified);
57  m_last_mission = -1;
58 }
59 
61 {
62 }
63 
64 void campaign_editor::DoDataExchange(CDataExchange* pDX)
65 {
66  CFormView::DoDataExchange(pDX);
67  //{{AFX_DATA_MAP(campaign_editor)
68  DDX_Control(pDX, IDC_SEXP_TREE, m_tree);
69  DDX_Control(pDX, IDC_FILELIST, m_filelist);
70  DDX_Text(pDX, IDC_NAME, m_name);
71  DDX_CBIndex(pDX, IDC_CAMPAIGN_TYPE, m_type);
72  DDX_Text(pDX, IDC_NUM_PLAYERS, m_num_players);
73  DDX_Text(pDX, IDC_DESC2, m_desc);
74  DDX_Text(pDX, IDC_MISSISON_LOOP_DESC, m_branch_desc);
77  DDX_Check(pDX, IDC_CUSTOM_TECH_DB, m_custom_tech_db);
78  //}}AFX_DATA_MAP
79 
80  DDV_MaxChars(pDX, m_desc, MISSION_DESC_LENGTH - 1);
81  DDV_MaxChars(pDX, m_branch_desc, MISSION_DESC_LENGTH - 1);
82 }
83 
84 BEGIN_MESSAGE_MAP(campaign_editor, CFormView)
85  //{{AFX_MSG_MAP(campaign_editor)
86  ON_BN_CLICKED(ID_LOAD, OnLoad)
87  ON_BN_CLICKED(IDC_ALIGN, OnAlign)
88  ON_BN_CLICKED(ID_CPGN_CLOSE, OnCpgnClose)
89  ON_NOTIFY(NM_RCLICK, IDC_SEXP_TREE, OnRclickTree)
90  ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_SEXP_TREE, OnBeginlabeleditSexpTree)
91  ON_NOTIFY(TVN_ENDLABELEDIT, IDC_SEXP_TREE, OnEndlabeleditSexpTree)
92  ON_NOTIFY(TVN_SELCHANGED, IDC_SEXP_TREE, OnSelchangedSexpTree)
93  ON_BN_CLICKED(IDC_MOVE_UP, OnMoveUp)
94  ON_BN_CLICKED(IDC_MOVE_DOWN, OnMoveDown)
95  ON_COMMAND(ID_END_EDIT, OnEndEdit)
96  ON_EN_CHANGE(IDC_BRIEFING_CUTSCENE, OnChangeBriefingCutscene)
97  ON_CBN_SELCHANGE(IDC_CAMPAIGN_TYPE, OnSelchangeType)
98  ON_BN_CLICKED(IDC_TOGGLE_LOOP, OnToggleLoop)
99  ON_BN_CLICKED(IDC_LOOP_BRIEF_BROWSE, OnBrowseLoopAni)
100  ON_BN_CLICKED(IDC_LOOP_BRIEF_SOUND_BROWSE, OnBrowseLoopSound)
101  ON_EN_CHANGE(IDC_MAIN_HALL, OnChangeMainHall)
102  ON_EN_CHANGE(IDC_DEBRIEFING_PERSONA, OnChangeDebriefingPersona)
103  ON_BN_CLICKED(IDC_CUSTOM_TECH_DB, OnCustomTechDB)
104  //}}AFX_MSG_MAP
105 END_MESSAGE_MAP()
106 
108 // campaign_editor diagnostics
109 
110 #ifdef _DEBUG
111 void campaign_editor::AssertValid() const
112 {
113  CFormView::AssertValid();
114 }
115 
116 void campaign_editor::Dump(CDumpContext& dc) const
117 {
118  CFormView::Dump(dc);
119 }
120 #endif //_DEBUG
121 
123 // campaign_editor message handlers
124 
125 void campaign_editor::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
126 {
127  UpdateData(FALSE);
128 }
129 
131 {
132  char buf[512];
133  int size, offset;
134 
135  if (Cur_campaign_mission < 0){
136  return;
137  }
138 
139  if (Campaign_modified){
140  if (Campaign_wnd->save_modified()){
141  return;
142  }
143  }
144 
146 
147  FREDDoc_ptr->SetPathName(buf);
148  Campaign_wnd->DestroyWindow();
149 
150 // if (FREDDoc_ptr->OnOpenDocument(Campaign.missions[Cur_campaign_mission].name)) {
151 // Bypass_clear_mission = 1;
152 // Campaign_wnd->DestroyWindow();
153 //
154 // } else {
155 // MessageBox("Failed to load mission!", "Error");
156 // }
157 }
158 
159 BOOL campaign_editor::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
160 {
161  int i;
162  BOOL r;
163  CComboBox *box;
164 
165  r = CFormView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
166  if (r) {
167  box = (CComboBox *) GetDlgItem(IDC_CAMPAIGN_TYPE);
168  box->ResetContent();
169  for (i=0; i<MAX_CAMPAIGN_TYPES; i++){
170  box->AddString(campaign_types[i]);
171  }
172  }
173 
174  return r;
175 }
176 
178 {
180  load_tree(0);
181 
182  if (!strlen(Campaign.filename))
184 
185  if (mission_campaign_load(Campaign.filename, NULL, 0)) {
186  MessageBox("Couldn't open Campaign file!", "Error");
188  return;
189  }
190 
191  Campaign_modified = 0;
193  initialize();
194 }
195 
197 {
200  Campaign_tree_viewp->Invalidate();
201 }
202 
203 void campaign_editor::initialize( int init_files )
204 {
206  m_tree.setup((CEdit *) GetDlgItem(IDC_HELP_BOX));
207  load_tree(0);
209 
210  // only initialize the file dialog box when the parameter says to. This should
211  // only happen when a campaign type changes
212  if ( init_files ){
214  }
215 
216  m_name = Campaign.name;
217  m_type = Campaign.type;
218  m_num_players.Format("%d", Campaign.num_players);
219 
220  if (Campaign.desc) {
222  } else {
223  m_desc = _T("");
224  }
225 
226  m_branch_desc = _T("");
227 
228  m_branch_brief_anim = _T("");
229  m_branch_brief_sound = _T("");
230 
231  // single player should hide the two dialog items about number of players allowed
232  if ( m_type == CAMPAIGN_TYPE_SINGLE ) {
233  GetDlgItem(IDC_NUM_PLAYERS)->ShowWindow( SW_HIDE );
234  GetDlgItem(IDC_PLAYERS_LABEL)->ShowWindow( SW_HIDE );
235  } else {
236  GetDlgItem(IDC_NUM_PLAYERS)->ShowWindow( SW_SHOW );
237  GetDlgItem(IDC_PLAYERS_LABEL)->ShowWindow( SW_SHOW );
238  }
239 
240  // set up the tech db checkbox
242 
243  UpdateData(FALSE);
244 }
245 
247 {
248  CEdit *bc_dialog, *bc_hall, *bc_persona;
249  char personatext[10];
250 
251  bc_dialog = (CEdit *) GetDlgItem(IDC_BRIEFING_CUTSCENE);
252  bc_hall = (CEdit *) GetDlgItem(IDC_MAIN_HALL);
253  bc_persona = (CEdit *) GetDlgItem(IDC_DEBRIEFING_PERSONA);
254 
255  // clear out the text for the briefing cutscene, and put in new text if specified
256  bc_dialog->SetWindowText("");
257  if ( strlen(Campaign.missions[num].briefing_cutscene) )
258  bc_dialog->SetWindowText(Campaign.missions[num].briefing_cutscene);
259 
260  // new main hall stuff
261  bc_hall->SetWindowText(Campaign.missions[num].main_hall.c_str());
262 
263  // new debriefing persona stuff
264  sprintf(personatext, "%d", Campaign.missions[num].debrief_persona_index);
265  bc_persona->SetWindowText(CString(personatext));
266 }
267 
269 {
270  char buf[MISSION_DESC_LENGTH];
271 
272  // get data from dlog box
273  UpdateData(TRUE);
274 
275  // update campaign name
277  Campaign.type = m_type;
278 
279  // update campaign desc
281  if (Campaign.desc) {
282  free(Campaign.desc);
283  }
284 
285  Campaign.desc = NULL;
286  if (strlen(buf)) {
287  Campaign.desc = strdup(buf);
288  }
289 
290  // update flags
292  if (m_custom_tech_db)
294 
295  // maybe update mission loop text
297 
298  // set the number of players in a multiplayer mission equal to the number of players in the first mission
300  if ( Campaign.num_missions == 0 ) {
301  Campaign.num_players = 0;
302  } else {
303  mission a_mission;
304 
305  get_mission_info(Campaign.missions[0].name, &a_mission);
306  Campaign.num_players = a_mission.num_players;
307  }
308  }
309 }
310 
312 {
314 }
315 
316 void campaign_editor::load_tree(int save_first)
317 {
318  char text[80];
319  int i;
320  HTREEITEM h;
321 
322  if (save_first)
323  save_tree();
324 
325  m_tree.clear_tree();
326  m_tree.DeleteAllItems();
327  m_num_links = 0;
328  UpdateData(TRUE);
330 
331  m_last_mission = Cur_campaign_mission;
332  if (Cur_campaign_mission < 0) {
333  GetDlgItem(IDC_SEXP_TREE)->EnableWindow(FALSE);
334  GetDlgItem(IDC_BRIEFING_CUTSCENE)->EnableWindow(FALSE);
335  GetDlgItem(IDC_MAIN_HALL)->EnableWindow(FALSE);
336  return;
337  }
338 
339  GetDlgItem(IDC_SEXP_TREE)->EnableWindow(TRUE);
340  GetDlgItem(IDC_BRIEFING_CUTSCENE)->EnableWindow(TRUE);
341  GetDlgItem(IDC_MAIN_HALL)->EnableWindow(TRUE);
342 
343  GetDlgItem(IDC_MISSISON_LOOP_DESC)->EnableWindow(FALSE);
344  GetDlgItem(IDC_LOOP_BRIEF_ANIM)->EnableWindow(FALSE);
345  GetDlgItem(IDC_LOOP_BRIEF_SOUND)->EnableWindow(FALSE);
346  GetDlgItem(IDC_LOOP_BRIEF_BROWSE)->EnableWindow(FALSE);
347  GetDlgItem(IDC_LOOP_BRIEF_SOUND_BROWSE)->EnableWindow(FALSE);
348 
349  for (i=0; i<Total_links; i++) {
350  if (Links[i].from == Cur_campaign_mission) {
351  Links[i].node = m_tree.load_sub_tree(Links[i].sexp, true, "do-nothing");
352  m_num_links++;
353 
354  if (Links[i].from == Links[i].to) {
355  strcpy_s(text, "Repeat mission");
356  } else if ( (Links[i].to == -1) && (Links[i].from != -1) ) {
357  strcpy_s(text, "End of Campaign");
358  } else {
359  sprintf(text, "Branch to %s", Campaign.missions[Links[i].to].name);
360  }
361 
362  // insert item into tree
363  int image, sel_image;
364  if (Links[i].is_mission_loop || Links[i].is_mission_fork) {
365  image = BITMAP_BLUE_DOT;
366  sel_image = BITMAP_GREEN_DOT;
367  } else {
368  image = BITMAP_BLACK_DOT;
369  sel_image = BITMAP_RED_DOT;
370  }
371 
372  h = m_tree.insert(text, image, sel_image);
373 
374  m_tree.SetItemData(h, Links[i].node);
375  m_tree.add_sub_tree(Links[i].node, h);
376  }
377  }
378 }
379 
380 void campaign_editor::OnRclickTree(NMHDR* pNMHDR, LRESULT* pResult)
381 {
383  *pResult = 0;
384 }
385 
387 {
388  TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
389 
390  if (m_tree.edit_label(pTVDispInfo->item.hItem) == 1) {
391  *pResult = 0;
392  Campaign_modified = 1;
393  } else {
394  *pResult = 1;
395  }
396 }
397 
398 void campaign_editor::OnEndlabeleditSexpTree(NMHDR* pNMHDR, LRESULT* pResult)
399 {
400  TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
401 
402  *pResult = m_tree.end_label_edit(pTVDispInfo->item);
403 }
404 
405 int campaign_editor::handler(int code, int node, char *str)
406 {
407  int i;
408 
409  switch (code) {
410  case ROOT_DELETED:
411  for (i=0; i<Total_links; i++){
412  if ((Links[i].from == Cur_campaign_mission) && (Links[i].node == node)){
413  break;
414  }
415  }
416 
418  m_num_links--;
419  return node;
420 
421  default:
422  Int3();
423  }
424 
425  return -1;
426 }
427 
429 {
430  int i;
431 
432  if (m_last_mission < 0){
433  return; // nothing to save
434  }
435 
436  for (i=0; i<Total_links; i++){
437  if (Links[i].from == m_last_mission) {
439  free_sexp2(Links[i].sexp);
440  Links[i].sexp = m_tree.save_tree(Links[i].node);
441  sexp_mark_persistent(Links[i].sexp);
442  }
443  }
444 
445  if (clear){
446  m_last_mission = -1;
447  }
448 }
449 
450 void campaign_editor::OnSelchangedSexpTree(NMHDR* pNMHDR, LRESULT* pResult)
451 {
452  int i, node;
453  HTREEITEM h, h2;
454 
455  // get handle of selected item
456  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
457  h = pNMTreeView->itemNew.hItem;
458  Assert(h);
459 
460  // update help on sexp
461  m_tree.update_help(h);
462 
463  // get handle of parent
464  while ((h2 = m_tree.GetParentItem(h))>0){
465  h = h2;
466  }
467 
468  // get identifier of parent
469  node = m_tree.GetItemData(h);
470  for (i=0; i<Total_links; i++){
471  if ((Links[i].from == Cur_campaign_mission) && (Links[i].node == node)){
472  break;
473  }
474  }
475 
476  if (i == Total_links) {
477  Cur_campaign_link = -1;
478  return;
479  }
480 
481  // update mission loop text
482  UpdateData(TRUE);
484 
487  Campaign_tree_viewp->Invalidate();
488  *pResult = 0;
489 }
490 
492 {
493  int i, last = -1;
495  HTREEITEM h1, h2;
496 
497  if (Cur_campaign_link >= 0) {
498  save_tree();
499  for (i=0; i<Total_links; i++){
500  if (Links[i].from == Cur_campaign_mission) {
501  if (i == Cur_campaign_link){
502  break;
503  }
504 
505  last = i;
506  }
507  }
508 
509  if ((last != -1) && (i < Total_links)) {
510  h1 = m_tree.GetParentItem(m_tree.handle(Links[i].node));
511  h2 = m_tree.GetParentItem(m_tree.handle(Links[last].node));
512  m_tree.swap_roots(h1, h2);
513  m_tree.SelectItem(m_tree.GetParentItem(m_tree.handle(Links[i].node)));
514 
515  temp = Links[last];
516  Links[last] = Links[i];
517  Links[i] = temp;
518  Cur_campaign_link = last;
519  }
520  }
521 
522  GetDlgItem(IDC_SEXP_TREE)->SetFocus();
523 }
524 
526 {
527  int i, j;
529  HTREEITEM h1, h2;
530 
531  if (Cur_campaign_link >= 0) {
532  save_tree();
533  for (i=0; i<Total_links; i++)
534  if (Links[i].from == Cur_campaign_mission)
535  if (i == Cur_campaign_link)
536  break;
537 
538  for (j=i+1; j<Total_links; j++)
539  if (Links[j].from == Cur_campaign_mission)
540  break;
541 
542  if (j < Total_links) {
543  h1 = m_tree.GetParentItem(m_tree.handle(Links[i].node));
544  h2 = m_tree.GetParentItem(m_tree.handle(Links[j].node));
545  m_tree.swap_roots(h1, h2);
546  m_tree.SelectItem(m_tree.GetParentItem(m_tree.handle(Links[i].node)));
547 
548  temp = Links[j];
549  Links[j] = Links[i];
550  Links[i] = temp;
551  Cur_campaign_link = j;
552  }
553  }
554 
555  GetDlgItem(IDC_SEXP_TREE)->SetFocus();
556 }
557 
558 void campaign_editor::swap_handler(int node1, int node2)
559 {
560  int index1, index2;
562 
563  for (index1=0; index1<Total_links; index1++){
564  if ((Links[index1].from == Cur_campaign_mission) && (Links[index1].node == node1)){
565  break;
566  }
567  }
568 
569  Assert(index1 < Total_links);
570  for (index2=0; index2<Total_links; index2++){
571  if ((Links[index2].from == Cur_campaign_mission) && (Links[index2].node == node2)){
572  break;
573  }
574  }
575 
576  Assert(index2 < Total_links);
577  temp = Links[index1];
578 // Links[index1] = Links[index2];
579  while (index1 < index2) {
580  Links[index1] = Links[index1 + 1];
581  index1++;
582  }
583 
584  while (index1 > index2 + 1) {
585  Links[index1] = Links[index1 - 1];
586  index1--;
587  }
588 
589  // update Cur_campaign_link
590  Cur_campaign_link = index1;
591 
592  Links[index1] = temp;
593 }
594 
595 void campaign_editor::insert_handler(int old, int node)
596 {
597  int i;
598 
599  for (i=0; i<Total_links; i++){
600  if ((Links[i].from == Cur_campaign_mission) && (Links[i].node == old)){
601  break;
602  }
603  }
604 
605  Assert(i < Total_links);
606  Links[i].node = node;
607  return;
608 }
609 
611 {
612  HWND h;
613  CWnd *w;
614 
615  w = GetFocus();
616  if (w) {
617  h = w->m_hWnd;
618  GetDlgItem(IDC_SEXP_TREE)->SetFocus();
619  ::SetFocus(h);
620  }
621 }
622 
624 {
625  CEdit *bc_dialog;
626 
627  bc_dialog = (CEdit *) GetDlgItem(IDC_BRIEFING_CUTSCENE);
628 
629  // maybe save off the current cutscene names.
630  if ( Cur_campaign_mission != -1 ) {
631 
632  // see if the contents of the edit box have changed. Luckily, this returns 0 when the edit box is
633  // cleared.
634  if ( bc_dialog->GetModify() ) {
636  Campaign_modified = 1;
637  }
638  }
639 
640 }
641 
642 // what to do when changing campaign type
644 {
645  // if campaign type is single player, then disable the multiplayer items
646  update();
647  initialize();
648  Campaign_modified = 1;
649 }
650 
651 
652 // update the loop mission text
654 {
656 
657  // update only if active link and there is a mission has mission loop or fork
658  if ( (Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork) ) {
660  if (Links[Cur_campaign_link].mission_branch_txt) {
661  free(Links[Cur_campaign_link].mission_branch_txt);
662  }
663  if (Links[Cur_campaign_link].mission_branch_brief_anim) {
664  free(Links[Cur_campaign_link].mission_branch_brief_anim);
665  }
666  if (Links[Cur_campaign_link].mission_branch_brief_sound) {
667  free(Links[Cur_campaign_link].mission_branch_brief_sound);
668  }
669 
670  if (strlen(buffer)) {
671  Links[Cur_campaign_link].mission_branch_txt = strdup(buffer);
672  } else {
674  }
675 
677  if(strlen(buffer)){
679  } else {
681  }
682 
684  if(strlen(buffer)){
686  } else {
688  }
689  }
690 }
691 
693 {
694  bool enable_branch_desc_window;
695 
696  enable_branch_desc_window = false;
697  if ((Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork)) {
698  enable_branch_desc_window = true;
699  }
700 
701  // maybe enable description window
702  GetDlgItem(IDC_MISSISON_LOOP_DESC)->EnableWindow(enable_branch_desc_window);
703  GetDlgItem(IDC_LOOP_BRIEF_ANIM)->EnableWindow(enable_branch_desc_window);
704  GetDlgItem(IDC_LOOP_BRIEF_SOUND)->EnableWindow(enable_branch_desc_window);
705  GetDlgItem(IDC_LOOP_BRIEF_BROWSE)->EnableWindow(enable_branch_desc_window);
706  GetDlgItem(IDC_LOOP_BRIEF_SOUND_BROWSE)->EnableWindow(enable_branch_desc_window);
707 
708  // set new text
709  if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_branch_txt && enable_branch_desc_window) {
711  } else {
712  m_branch_desc = _T("");
713  }
714 
715  // set new text
716  if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_branch_brief_anim && enable_branch_desc_window) {
718  } else {
719  m_branch_brief_anim = _T("");
720  }
721 
722  // set new text
723  if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_branch_brief_sound && enable_branch_desc_window) {
725  } else {
726  m_branch_brief_sound = _T("");
727  }
728 
729  // reset text
730  UpdateData(FALSE);
731 }
732 
734 {
735  // check if branch selected
736  if (Cur_campaign_link == -1) {
737  return;
738  }
739 
740  // store mission loop text
741  UpdateData(TRUE);
742 
743  if ( (Cur_campaign_link >= 0) && (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork) ) {
744  if (Links[Cur_campaign_link].mission_branch_txt) {
745  free(Links[Cur_campaign_link].mission_branch_txt);
746  }
747 
748  if (Links[Cur_campaign_link].mission_branch_brief_anim) {
749  free(Links[Cur_campaign_link].mission_branch_brief_anim);
750  }
751 
752  if (Links[Cur_campaign_link].mission_branch_brief_sound) {
753  free(Links[Cur_campaign_link].mission_branch_brief_sound);
754  }
755 
757 
759  if (m_branch_desc && strlen(buffer)) {
760  Links[Cur_campaign_link].mission_branch_txt = strdup(buffer);
761  } else {
763  }
764 
766  if (m_branch_brief_anim && strlen(buffer)) {
768  } else {
770  }
771 
773  if (m_branch_brief_sound && strlen(buffer)) {
775  } else {
777  }
778  }
779 
780  // toggle to mission_loop setting
783 
784  // reset loop desc window (gray if inactive)
786 
787  // set root icon
788  int bitmap1, bitmap2;
789  if (Links[Cur_campaign_link].is_mission_loop || Links[Cur_campaign_link].is_mission_fork) {
790  bitmap2 = BITMAP_GREEN_DOT;
791  bitmap1 = BITMAP_BLUE_DOT;
792  } else {
793  bitmap1 = BITMAP_BLACK_DOT;
794  bitmap2 = BITMAP_RED_DOT;
795  }
796 
797  // Search for item and update bitmap
798  HTREEITEM h = m_tree.GetRootItem();
799  while (h) {
800  if ((int) m_tree.GetItemData(h) == Links[Cur_campaign_link].node) {
801  m_tree.SetItemImage(h, bitmap1, bitmap2);
802  break;
803  }
804 
805  h = m_tree.GetNextSiblingItem(h);
806  }
807 
808  // set to redraw
809  Campaign_tree_viewp->Invalidate();
810 }
811 
813 {
814  int pushed_dir;
815 
816  UpdateData(TRUE);
817 
818  // switch directories
819  pushed_dir = cfile_push_chdir(CF_TYPE_INTERFACE);
820  CFileDialog dlg(TRUE, "ani", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "Ani Files (*.ani)|*.ani");
821 
822  if (dlg.DoModal() == IDOK) {
823  m_branch_brief_anim = dlg.GetFileName();
824  UpdateData(FALSE);
825  }
826 
827  // move back to the proper directory
828  if (!pushed_dir){
829  cfile_pop_dir();
830  }
831 }
832 
834 {
835  int pushed_dir;
836 
837  UpdateData(TRUE);
838 
839  // switch directories
841  CFileDialog dlg(TRUE, "wav", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
842  "Voice Files (*.ogg, *.wav)|*.ogg;*.wav|Ogg Vorbis Files (*.ogg)|*.ogg|Wave Files (*.wav)|*.wav||");
843 
844  if (dlg.DoModal() == IDOK) {
845  m_branch_brief_sound = dlg.GetFileName();
846  UpdateData(FALSE);
847  }
848 
849  // move back to the proper directory
850  if (!pushed_dir){
851  cfile_pop_dir();
852  }
853 }
854 
856 {
857  CString str;
858  UpdateData(TRUE);
859 
860  if (Cur_campaign_mission >= 0)
861  {
862  GetDlgItem(IDC_MAIN_HALL)->GetWindowText(str);
864  }
865 }
866 
868 {
869  CString str;
870  int persona;
871 
872  UpdateData(TRUE);
873 
874  if (Cur_campaign_mission >= 0)
875  {
876  GetDlgItem(IDC_DEBRIEFING_PERSONA)->GetWindowText(str);
877  persona = atoi(str);
878 
879  if (persona < 0 || persona > 0xff)
880  persona = 0;
881 
883  }
884 }
885 
887 {
888  UpdateData(TRUE);
889 
890  if (m_custom_tech_db)
892  else
894 }
SCP_string sexp
Definition: sexp.cpp:25556
#define MAX_FILENAME_LEN
Definition: pstypes.h:324
void * HWND
Definition: config.h:104
int i
Definition: multi_pxo.cpp:466
int Total_links
#define CAMPAIGN_TYPE_SINGLE
int Cur_campaign_link
void swap_handler(int node1, int node2)
#define BITMAP_GREEN_DOT
Definition: sexp_tree.h:52
afx_msg void OnChangeMainHall()
#define MODE_CAMPAIGN
Definition: sexp_tree.h:68
virtual void OnUpdate(CView *pSender, LPARAM lHint, CObject *pHint)
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
void add_sub_tree(int node, HTREEITEM root)
Definition: sexp_tree.cpp:476
#define IDC_NAME
Definition: resource.h:735
#define MAX_CAMPAIGN_TYPES
char name[NAME_LENGTH]
afx_msg void OnBrowseLoopSound()
void save_tree(int clear=1)
campaign_editor * Campaign_tree_formp
virtual void DoDataExchange(CDataExchange *pDX)
#define IDC_HELP_BOX
Definition: resource.h:872
#define IDC_CAMPAIGN_TYPE
Definition: resource.h:967
#define IDC_DESC2
Definition: resource.h:974
Assert(pm!=NULL)
#define IDC_LOOP_BRIEF_SOUND
Definition: resource.h:1041
#define IDC_TOGGLE_LOOP
Definition: resource.h:570
ubyte debrief_persona_index
GLenum GLsizei GLenum GLenum const GLvoid * image
Definition: Glext.h:5230
void initialize(int init_files=1)
int cfile_pop_dir()
Definition: cfile.cpp:381
afx_msg void OnEndlabeleditSexpTree(NMHDR *pNMHDR, LRESULT *pResult)
afx_msg void OnAlign()
char briefing_cutscene[NAME_LENGTH]
#define TRUE
Definition: pstypes.h:399
afx_msg void OnLoad()
afx_msg void OnCpgnClose()
#define ID_LOAD
Definition: resource.h:835
#define CF_DEFAULT_VALUE
void setup(CEdit *ptr=NULL)
Definition: sexp_tree.cpp:3754
int edit_label(HTREEITEM h)
Definition: sexp_tree.cpp:1349
unsigned int UINT
Definition: config.h:82
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
#define IDC_MISSISON_LOOP_DESC
Definition: resource.h:972
GLsizeiptr size
Definition: Glext.h:5496
void deconvert_multiline_string(char *dest, const CString &str, int max_len)
Definition: management.cpp:184
#define Int3()
Definition: pstypes.h:292
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
afx_msg void OnBeginlabeleditSexpTree(NMHDR *pNMHDR, LRESULT *pResult)
#define IDC_CUSTOM_TECH_DB
Definition: resource.h:1056
void right_clicked(int mode=0)
Definition: sexp_tree.cpp:570
char * name
long LPARAM
Definition: config.h:101
#define IDC_LOOP_BRIEF_SOUND_BROWSE
Definition: resource.h:979
HWND DWORD code
Definition: vddraw.h:425
void swap_roots(HTREEITEM one, HTREEITEM two)
Definition: sexp_tree.cpp:3623
campaign_tree_view * Campaign_tree_viewp
int cfile_push_chdir(int type)
Push current directory onto a 'stack' and change to a new directory.
Definition: cfile.cpp:342
void update_help(HTREEITEM h)
Definition: sexp_tree.cpp:3891
void mission_selected(int num)
void sexp_mark_persistent(int n)
Definition: sexp.cpp:1220
void convert_multiline_string(CString &dest, const SCP_string &src)
Definition: management.cpp:169
afx_msg void OnMoveDown()
GLintptr offset
Definition: Glext.h:5497
int cf_find_file_location(const char *filespec, int pathtype, int max_out, char *pack_filename, int *size, int *offset, bool localize=false)
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
afx_msg void OnToggleLoop()
afx_msg void OnCustomTechDB()
#define IDC_MAIN_HALL
Definition: resource.h:737
int end_label_edit(TVITEMA &item)
Definition: sexp_tree.cpp:1412
virtual ~campaign_editor()
campaign_sexp_tree m_tree
#define CF_TYPE_VOICE_CMD_BRIEF
Definition: cfile.h:56
void insert_handler(int old, int node)
#define BITMAP_RED_DOT
Definition: sexp_tree.h:55
#define w(p)
Definition: modelsinc.h:68
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
#define IDC_BRIEFING_CUTSCENE
Definition: resource.h:914
char Default_campaign_file_name[MAX_FILENAME_LEN-4]
void sexp_unmark_persistent(int n)
Definition: sexp.cpp:1242
int free_sexp2(int num)
Definition: sexp.cpp:1321
int Cur_campaign_mission
GLuint buffer
Definition: Glext.h:5492
afx_msg void OnEndEdit()
afx_msg void OnMoveUp()
#define IDC_ALIGN
Definition: resource.h:836
afx_msg void OnSelchangedSexpTree(NMHDR *pNMHDR, LRESULT *pResult)
CFREDDoc * FREDDoc_ptr
Definition: freddoc.cpp:90
#define MISSION_DESC_LENGTH
Definition: globals.h:28
#define CF_CUSTOM_TECH_DATABASE
unsigned long DWORD
Definition: config.h:90
#define CF_TYPE_INTERFACE
Definition: cfile.h:63
HTREEITEM insert(LPCTSTR lpszItem, int image=BITMAP_ROOT, int sel_image=BITMAP_ROOT, HTREEITEM hParent=TVI_ROOT, HTREEITEM hInsertAfter=TVI_LAST)
Definition: sexp_tree.cpp:3832
campaign_tree_wnd * Campaign_wnd
#define ID_END_EDIT
Definition: resource.h:1408
unsigned char ubyte
Definition: pstypes.h:62
int get_mission_info(const char *filename, mission *mission_p, bool basic)
void string_copy(char *dest, const CString &src, int max_len, int modify)
Definition: management.cpp:142
#define ROOT_DELETED
Definition: sexp_tree.h:71
CString m_branch_brief_anim
int handler(int code, int node, char *str=NULL)
#define IDC_LOOP_BRIEF_ANIM
Definition: resource.h:1039
#define IDC_FILELIST
Definition: resource.h:597
int BOOL
Definition: config.h:80
#define BITMAP_BLACK_DOT
Definition: sexp_tree.h:53
GLuint GLuint num
Definition: Glext.h:9089
SCP_string main_hall
int load_sub_tree(int index, bool valid, const char *text)
Definition: sexp_tree.cpp:535
afx_msg void OnChangeDebriefingPersona()
campaign Campaign
int mission_campaign_load(char *filename, player *pl, int load_savefile, bool reset_stats)
#define NAME_LENGTH
Definition: globals.h:15
afx_msg void OnChangeBriefingCutscene()
CString m_branch_brief_sound
int save_tree(int node=-1)
Definition: sexp_tree.cpp:237
HTREEITEM handle(int node)
Definition: sexp_tree.cpp:3851
long LRESULT
Definition: config.h:100
int Campaign_modified
#define CF_TYPE_MISSIONS
Definition: cfile.h:74
int MessageBox(HWND h, const char *s1, const char *s2, int i)
#define ID_CPGN_CLOSE
Definition: resource.h:839
campaign_filelist_box m_filelist
#define IDC_SEXP_TREE
Definition: resource.h:837
afx_msg void OnRclickTree(NMHDR *pNMHDR, LRESULT *pResult)
#define IDC_MOVE_DOWN
Definition: resource.h:562
int num_players
Definition: missionparse.h:140
char filename[MAX_FILENAME_LEN]
int temp
Definition: lua.cpp:4996
#define IDC_MOVE_UP
Definition: resource.h:838
#define IDC_PLAYERS_LABEL
Definition: resource.h:952
afx_msg void OnClose()
#define FALSE
Definition: pstypes.h:400
char * campaign_types[MAX_CAMPAIGN_TYPES]
#define IDC_LOOP_BRIEF_BROWSE
Definition: resource.h:337
#define IDC_NUM_PLAYERS
Definition: resource.h:950
cmission missions[MAX_CAMPAIGN_MISSIONS]
void clear_tree(const char *op=NULL)
Definition: sexp_tree.cpp:99
afx_msg void OnCpgnFileNew()
#define IDC_DEBRIEFING_PERSONA
Definition: resource.h:738
afx_msg void OnBrowseLoopAni()
#define BITMAP_BLUE_DOT
Definition: sexp_tree.h:54
void load_tree(int save=1)
#define strcpy_s(...)
Definition: safe_strings.h:67
campaign_tree_link Links[MAX_CAMPAIGN_TREE_LINKS]
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT &rect, CWnd *pParentWnd, UINT nID, CCreateContext *pContext=NULL)
afx_msg void OnSelchangeType()