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