]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/ship_select.cpp
fix issue with looping audio streams
[taylor/freespace2.git] / src / fred2 / ship_select.cpp
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
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/FRED2/ship_select.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Object selection (marking) dialog box handling code
16  *
17  * $Log$
18  * Revision 1.3  2002/06/09 04:41:16  relnev
19  * added copyright header
20  *
21  * Revision 1.2  2002/05/07 03:16:44  theoddone33
22  * The Great Newline Fix
23  *
24  * Revision 1.1.1.1  2002/05/03 03:28:09  root
25  * Initial import.
26  *
27  * 
28  * 2     10/07/98 6:28p Dave
29  * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
30  * Fred. Globalized mission and campaign file extensions. Removed Silent
31  * Threat specific code.
32  * 
33  * 1     10/07/98 3:01p Dave
34  * 
35  * 1     10/07/98 3:00p Dave
36  * 
37  * 21    2/13/98 11:48a Hoffoss
38  * Fixed up some bugs with object selection when filters are turned off.
39  * 
40  * 20    9/16/97 9:41p Hoffoss
41  * Changed Fred code around to stop using Parse_player structure for
42  * player information, and use actual ships instead.
43  * 
44  * 19    9/09/97 10:29a Hoffoss
45  * Added support for neutral team, and fixed changes made to how team is
46  * used in ship structure.
47  * 
48  * 18    9/06/97 2:13p Mike
49  * Replace support for TEAM_NEUTRAL
50  * 
51  * 17    8/26/97 11:08a Hoffoss
52  * Added waypoint paths to object selection dialog.
53  * 
54  * 16    7/28/97 5:10p Hoffoss
55  * Removed all occurances of neutral team from Fred.
56  * 
57  * 15    7/24/97 2:43p Hoffoss
58  * Made changes whiteside requested.  Double clicking acts as clicking ok
59  * button.
60  * 
61  * 14    7/24/97 10:24a Mike
62  * Restore support for Unknown team
63  * 
64  * 13    7/10/97 11:24a Hoffoss
65  * Fixed bugs in briefing editor system.  Make icon button not updating
66  * when selecting ships via list select, and after making icon, it wasn't
67  * being displayed, though it was selected.
68  * 
69  * 12    5/26/97 10:30a Hoffoss
70  * Added select wing to object select dialog.
71  * 
72  * 11    5/14/97 4:08p Lawrance
73  * removing my_index from game arrays
74  * 
75  * 10    3/07/97 4:37p Mike
76  * Make rockeye missile home.
77  * Remove UNKNOWN and NEUTRAL teams.
78  * 
79  * 9     2/17/97 5:28p Hoffoss
80  * Checked RCS headers, added them were missing, changing description to
81  * something better, etc where needed.
82  *
83  * $NoKeywords: $
84  */
85
86 #include "stdafx.h"
87 #include "fred.h"
88 #include "ship_select.h"
89 #include "linklist.h"
90 #include "object.h"
91 #include "ship.h"
92 #include "management.h"
93 #include "fredview.h"
94
95 #define ACTIVITY_SHIP 1
96 #define ACTIVITY_WING 2
97
98 #ifdef _DEBUG
99 #define new DEBUG_NEW
100 #undef THIS_FILE
101 static char THIS_FILE[] = __FILE__;
102 #endif
103
104 int filter_ships = TRUE;
105 int filter_starts = TRUE;
106 int filter_waypoints = TRUE;
107 int filter_friendly = TRUE;
108 int filter_hostile = TRUE;
109 int filter_neutral = TRUE;
110 int filter_unknown = TRUE;
111
112 /////////////////////////////////////////////////////////////////////////////
113 // ship_select dialog
114
115 ship_select::ship_select(CWnd* pParent /*=NULL*/)
116         : CDialog(ship_select::IDD, pParent)
117 {
118         //{{AFX_DATA_INIT(ship_select)
119         m_filter_ships = TRUE;
120         m_filter_starts = TRUE;
121         m_filter_waypoints = TRUE;
122         m_filter_friendly = TRUE;
123         m_filter_hostile = TRUE;
124         m_filter_neutral = TRUE;
125         m_filter_unknown = TRUE;
126         //}}AFX_DATA_INIT
127         
128         m_filter_ships = filter_ships;
129         m_filter_starts = filter_starts;
130         m_filter_waypoints = filter_waypoints;
131         m_filter_friendly = filter_friendly;
132         m_filter_hostile = filter_hostile;
133         m_filter_neutral = filter_neutral;
134         m_filter_unknown = filter_unknown;
135         activity = 0;
136 }
137
138 void ship_select::DoDataExchange(CDataExchange* pDX)
139 {
140         CDialog::DoDataExchange(pDX);
141         //{{AFX_DATA_MAP(ship_select)
142         DDX_Control(pDX, IDC_WING_LIST, m_wing_list);
143         DDX_Control(pDX, IDC_SHIP_LIST, m_ship_list);
144         DDX_Check(pDX, IDC_FILTER_SHIPS, m_filter_ships);
145         DDX_Check(pDX, IDC_FILTER_STARTS, m_filter_starts);
146         DDX_Check(pDX, IDC_FILTER_WAYPOINTS, m_filter_waypoints);
147         DDX_Check(pDX, IDC_FILTER_SHIPS_FRIENDLY, m_filter_friendly);
148         DDX_Check(pDX, IDC_FILTER_SHIPS_HOSTILE, m_filter_hostile);
149         DDX_Check(pDX, IDC_FILTER_SHIPS_NEUTRAL, m_filter_neutral);
150         DDX_Check(pDX, IDC_FILTER_SHIPS_UNKNOWN, m_filter_unknown);
151         //}}AFX_DATA_MAP
152 }
153
154 BEGIN_MESSAGE_MAP(ship_select, CDialog)
155         //{{AFX_MSG_MAP(ship_select)
156         ON_CBN_SELCHANGE(IDC_WING_DISPLAY_FILTER, OnSelchangeWingDisplayFilter)
157         ON_BN_CLICKED(IDC_FILTER_SHIPS, OnFilterShips)
158         ON_BN_CLICKED(IDC_FILTER_STARTS, OnFilterStarts)
159         ON_BN_CLICKED(IDC_FILTER_WAYPOINTS, OnFilterWaypoints)
160         ON_BN_CLICKED(IDC_FILTER_SHIPS_FRIENDLY, OnFilterShipsFriendly)
161         ON_BN_CLICKED(IDC_FILTER_SHIPS_HOSTILE, OnFilterShipsHostile)
162         ON_BN_CLICKED(IDC_FILTER_SHIPS_NEUTRAL, OnFilterShipsNeutral)
163         ON_BN_CLICKED(IDC_FILTER_SHIPS_UNKNOWN, OnFilterShipsUnknown)
164         ON_BN_CLICKED(IDC_CLEAR, OnClear)
165         ON_BN_CLICKED(IDC_ALL, OnAll)
166         ON_BN_CLICKED(IDC_INVERT, OnInvert)
167         ON_LBN_DBLCLK(IDC_SHIP_LIST, OnDblclkShipList)
168         ON_LBN_SELCHANGE(IDC_WING_LIST, OnSelchangeWingList)
169         ON_LBN_SELCHANGE(IDC_SHIP_LIST, OnSelchangeShipList)
170         ON_LBN_DBLCLK(IDC_WING_LIST, OnDblclkWingList)
171         //}}AFX_MSG_MAP
172 END_MESSAGE_MAP()
173
174 /////////////////////////////////////////////////////////////////////////////
175 // ship_select message handlers
176
177 void ship_select::OnSelchangeWingDisplayFilter() 
178 {
179         UpdateData(TRUE);
180         create_list();
181 }
182
183 BOOL ship_select::OnInitDialog() 
184 {
185         int i, flags;
186         object *ptr;
187
188         wlist_size = wplist_size = 0;
189         CDialog::OnInitDialog();
190
191         ptr = GET_FIRST(&obj_used_list);
192         while (ptr != END_OF_LIST(&obj_used_list))
193         {
194                 flags = ptr->flags & ~OF_TEMP_MARKED;
195                 if (flags & OF_MARKED)
196                         flags |= OF_TEMP_MARKED;
197                 else
198                         flags &= ~OF_TEMP_MARKED;
199
200                 ptr->flags = flags;
201                 ptr = GET_NEXT(ptr);
202         }
203
204         list_size = 0;
205         create_list();
206         GetDlgItem(IDC_FILTER_SHIPS_FRIENDLY)->EnableWindow(m_filter_ships);
207         GetDlgItem(IDC_FILTER_SHIPS_HOSTILE)->EnableWindow(m_filter_ships);
208         GetDlgItem(IDC_FILTER_SHIPS_NEUTRAL)->EnableWindow(m_filter_ships);
209         GetDlgItem(IDC_FILTER_SHIPS_UNKNOWN)->EnableWindow(m_filter_ships);
210
211         // Elements 0 - wlist_size are wings, and elements wlist_size - wplist_size are waypoint paths
212         m_wing_list.ResetContent();
213         wlist_size = 0;
214         for (i=0; i<MAX_WINGS; i++)
215                 if (Wings[i].wave_count) {
216                         m_wing_list.AddString(Wings[i].name);
217                         wing_sel_last[wlist_size] = 0;
218                         wing_index[wlist_size++] = i;
219                 }
220
221         wplist_size = wlist_size;
222         for (i=0; i<Num_waypoint_lists; i++) {
223                 m_wing_list.AddString(Waypoint_lists[i].name);
224                 wing_sel_last[wplist_size] = 0;
225                 wing_index[wplist_size++] = i;
226         }
227
228         return TRUE;
229 }
230
231 void ship_select::create_list()
232 {
233         char text[512];
234         int flag;
235         object *ptr;
236
237         update_status();
238         m_ship_list.ResetContent();
239         list_size = 0;
240
241         if (m_filter_starts)
242         {
243                 ptr = GET_FIRST(&obj_used_list);
244                 while (ptr != END_OF_LIST(&obj_used_list))
245                 {
246                         if (ptr->type == OBJ_START)
247                         {
248                                 m_ship_list.AddString(Ships[ptr->instance].ship_name);
249                                 obj_index[list_size++] = ptr;
250                                 if (ptr->flags & OF_TEMP_MARKED)
251                                         m_ship_list.SetSel(list_size - 1);
252                         }
253
254                         ptr = GET_NEXT(ptr);
255                 }
256         }
257
258         if (m_filter_ships) {
259                 ptr = GET_FIRST(&obj_used_list);
260                 while (ptr != END_OF_LIST(&obj_used_list))
261                 {
262                         if (ptr->type == OBJ_SHIP)
263                         {
264                                 flag = 0;
265                                 switch (Ships[ptr->instance].team)
266                                 {
267                                         case TEAM_FRIENDLY:
268                                                 flag = m_filter_friendly;
269                                                 break;
270
271                                         case TEAM_HOSTILE:
272                                                 flag = m_filter_hostile;
273                                                 break;
274
275                                         case TEAM_NEUTRAL:
276                                                 flag = m_filter_neutral;
277                                                 break;
278
279                                         case TEAM_UNKNOWN:
280                                                 flag = m_filter_unknown;
281                                                 break;
282
283                                         default:
284                                                 flag = m_filter_hostile;
285                                                 break;
286                                 }
287
288                                 if (flag)
289                                 {
290                                         m_ship_list.AddString(Ships[ptr->instance].ship_name);
291                                         obj_index[list_size++] = ptr;
292                                         if (ptr->flags & OF_TEMP_MARKED)
293                                                 m_ship_list.SetSel(list_size - 1);
294                                 }
295                         }
296
297                         ptr = GET_NEXT(ptr);
298                 }
299         }
300
301         if (m_filter_waypoints)
302         {
303                 ptr = GET_FIRST(&obj_used_list);
304                 while (ptr != END_OF_LIST(&obj_used_list))
305                 {
306                         if (ptr->type == OBJ_WAYPOINT)
307                         {
308                                 sprintf(text, "%s:%d", Waypoint_lists[ptr->instance / 65536].name,
309                                         (ptr->instance & 0xffff) + 1);
310                                 m_ship_list.AddString(text);
311                                 obj_index[list_size++] = ptr;
312                                 if (ptr->flags & OF_TEMP_MARKED)
313                                         m_ship_list.SetSel(list_size - 1);
314                         }
315
316                         ptr = GET_NEXT(ptr);
317                 }
318         }
319 }
320
321 void ship_select::OnOK()
322 {
323         object *ptr;
324
325         unmark_all();
326         update_status();
327         ptr = GET_FIRST(&obj_used_list);
328         while (ptr != END_OF_LIST(&obj_used_list))
329         {
330                 if (ptr->flags & OF_TEMP_MARKED)
331                         mark_object(OBJ_INDEX(ptr));
332
333                 ptr = GET_NEXT(ptr);
334         }
335
336         if (query_valid_object() && (Marked == 1) && (Objects[cur_object_index].type == OBJ_POINT)) {
337                 SDL_assert(Briefing_dialog);
338                 Briefing_dialog->icon_select(Objects[cur_object_index].instance);
339
340         } else {
341                 if (Briefing_dialog)
342                         Briefing_dialog->icon_select(-1);
343         }
344
345         filter_ships = m_filter_ships;
346         filter_starts = m_filter_starts;
347         filter_waypoints = m_filter_waypoints;
348         filter_friendly = m_filter_friendly;
349         filter_hostile = m_filter_hostile;
350         filter_neutral = m_filter_neutral;
351         filter_unknown = m_filter_unknown;
352         CDialog::OnOK();
353 }
354
355 void ship_select::update_status()
356 {
357         int i, z;
358         object *ptr;
359
360         ptr = GET_FIRST(&obj_used_list);
361         while (ptr != END_OF_LIST(&obj_used_list)) {
362                 ptr->flags &= ~OF_TEMP_MARKED;
363                 ptr = GET_NEXT(ptr);
364         }
365
366         for (i=0; i<list_size; i++)
367         {
368                 z = m_ship_list.GetSel(i);
369                 if (z < 1)
370                         obj_index[i]->flags &= ~OF_TEMP_MARKED;
371                 else
372                         obj_index[i]->flags |= OF_TEMP_MARKED;
373         }
374
375         OnSelchangeShipList();
376 }
377
378 void ship_select::OnFilterShips() 
379 {
380         UpdateData(TRUE);
381         create_list();
382         GetDlgItem(IDC_FILTER_SHIPS_FRIENDLY)->EnableWindow(m_filter_ships);
383         GetDlgItem(IDC_FILTER_SHIPS_HOSTILE)->EnableWindow(m_filter_ships);
384         GetDlgItem(IDC_FILTER_SHIPS_NEUTRAL)->EnableWindow(m_filter_ships);
385         GetDlgItem(IDC_FILTER_SHIPS_UNKNOWN)->EnableWindow(m_filter_ships);
386 }
387
388 void ship_select::OnFilterStarts() 
389 {
390         UpdateData(TRUE);
391         create_list();
392 }
393
394 void ship_select::OnFilterWaypoints() 
395 {
396         UpdateData(TRUE);
397         create_list();
398 }
399
400 void ship_select::OnFilterShipsFriendly() 
401 {
402         UpdateData(TRUE);
403         create_list();
404 }
405
406 void ship_select::OnFilterShipsHostile() 
407 {
408         UpdateData(TRUE);
409         create_list();
410 }
411
412 void ship_select::OnFilterShipsNeutral() 
413 {
414         UpdateData(TRUE);
415         create_list();
416 }
417
418 void ship_select::OnFilterShipsUnknown() 
419 {
420         UpdateData(TRUE);
421         create_list();
422 }
423
424 void ship_select::OnClear() 
425 {
426         int i;
427         object *ptr;
428
429         ptr = GET_FIRST(&obj_used_list);
430         while (ptr != END_OF_LIST(&obj_used_list))
431         {
432                 ptr->flags &= ~OF_TEMP_MARKED;
433                 ptr = GET_NEXT(ptr);
434         }
435
436         for (i=0; i<list_size; i++)
437                 m_ship_list.SetSel(i, FALSE);
438
439         for (i=0; i<wplist_size; i++) {
440                 wing_sel_last[i] = 0;
441                 m_wing_list.SetSel(i, FALSE);
442         }
443 }
444
445 void ship_select::OnAll() 
446 {
447         int i;
448
449         for (i=0; i<list_size; i++)
450         {
451                 obj_index[i]->flags |= OF_TEMP_MARKED;
452                 m_ship_list.SetSel(i);
453         }
454
455         for (i=0; i<wplist_size; i++) {
456                 wing_sel_last[i] = 1;
457                 m_wing_list.SetSel(i, TRUE);
458         }
459 }
460
461 void ship_select::OnInvert() 
462 {
463         int i, z;
464
465         for (i=0; i<list_size; i++)
466         {
467                 z = m_ship_list.GetSel(i);
468                 if (z > 0)
469                 {
470                         obj_index[i]->flags &= ~OF_TEMP_MARKED;
471                         m_ship_list.SetSel(i, FALSE);
472
473                 } else {
474                         obj_index[i]->flags |= OF_TEMP_MARKED;
475                         m_ship_list.SetSel(i);
476                 }
477         }
478
479         OnSelchangeShipList();
480 }
481
482 void ship_select::OnDblclkShipList() 
483 {
484         OnOK();
485
486 /*      int i, j, z, wing;
487
488         z = m_ship_list.GetCaretIndex();
489         switch (obj_index[z]->type) {
490                 case OBJ_SHIP:
491                         wing = Ships[obj_index[z]->instance].wingnum;
492                         if (wing >= 0) {
493                                 for (i=0; i<Wings[wing].wave_count; i++)
494                                         for (j=0; j<list_size; j++)
495                                                 if (OBJ_INDEX(obj_index[j]) == wing_objects[wing][i]) {
496                                                         m_ship_list.SetSel(j);
497                                                         break;
498                                                 }
499
500                                 for (i=0; i<wlist_size; i++)
501                                         if (wing_index[i] == wing) {
502                                                 m_wing_list.SetSel(i);
503                                                 wing_sel_last[i] = 1;
504                                                 break;
505                                         }
506                         }
507
508                         break;
509
510                 case OBJ_WAYPOINT:
511                         break;
512         }*/
513 }
514
515 void ship_select::OnSelchangeWingList() 
516 {
517         int i, j, k, z;
518
519         if (activity)
520                 return;
521
522         activity = ACTIVITY_WING;
523         for (i=0; i<wlist_size; i++) {
524                 z = (m_wing_list.GetSel(i) > 0) ? 1 : 0;
525                 if (z != wing_sel_last[i]) {
526                         for (j=0; j<Wings[wing_index[i]].wave_count; j++)
527                                 for (k=0; k<list_size; k++)
528                                         if (OBJ_INDEX(obj_index[k]) == wing_objects[wing_index[i]][j]) {
529                                                 m_ship_list.SetSel(k, z ? TRUE : FALSE);
530                                                 break;
531                                         }
532
533                         wing_sel_last[i] = z;
534                 }
535         }
536
537         for (i=wlist_size; i<wplist_size; i++) {
538                 z = (m_wing_list.GetSel(i) > 0) ? 1 : 0;
539                 if (z != wing_sel_last[i]) {
540                         for (j=0; j<Waypoint_lists[wing_index[i]].count; j++)
541                                 for (k=0; k<list_size; k++)
542                                         if ((obj_index[k]->type == OBJ_WAYPOINT) && (obj_index[k]->instance == wing_index[i] * 65536 + j)) {
543                                                 m_ship_list.SetSel(k, z ? TRUE : FALSE);
544                                                 break;
545                                         }
546
547                         wing_sel_last[i] = z;
548                 }
549         }
550
551         activity = 0;
552 }
553
554 void ship_select::OnSelchangeShipList() 
555 {
556         int i, j, k, count;
557
558         if (activity)
559                 return;
560
561         activity = ACTIVITY_SHIP;
562         for (i=0; i<wlist_size; i++) {
563                 count = 0;
564                 for (j=0; j<Wings[wing_index[i]].wave_count; j++)
565                         for (k=0; k<list_size; k++)
566                                 if (OBJ_INDEX(obj_index[k]) == wing_objects[wing_index[i]][j]) {
567                                         if (m_ship_list.GetSel(k))
568                                                 count++;
569
570                                         break;
571                                 }
572
573                 if (count == Wings[wing_index[i]].wave_count)
574                         wing_sel_last[i] = 1;
575                 else
576                         wing_sel_last[i] = 0;
577
578                 m_wing_list.SetSel(i, wing_sel_last[i] ? TRUE : FALSE);
579         }
580
581         for (i=wlist_size; i<wplist_size; i++) {
582                 count = 0;
583                 for (j=0; j<Waypoint_lists[wing_index[i]].count; j++)
584                         for (k=0; k<list_size; k++)
585                                 if ((obj_index[k]->type == OBJ_WAYPOINT) && (obj_index[k]->instance == wing_index[i] * 65536 + j)) {
586                                         if (m_ship_list.GetSel(k))
587                                                 count++;
588
589                                         break;
590                                 }
591
592                 if (count == Waypoint_lists[wing_index[i]].count)
593                         wing_sel_last[i] = 1;
594                 else
595                         wing_sel_last[i] = 0;
596
597                 m_wing_list.SetSel(i, wing_sel_last[i] ? TRUE : FALSE);
598         }
599
600         activity = 0;
601 }
602
603 void ship_select::OnDblclkWingList() 
604 {
605         OnOK();
606 }
607