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