]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/ignoreordersdlg.cpp
Initial revision
[taylor/freespace2.git] / src / fred2 / ignoreordersdlg.cpp
1 /*
2  * $Logfile: /Freespace2/code/FRED2/IgnoreOrdersDlg.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * C code for dialog to set which orders from the player that a particular ship should ignore
8  *
9  */
10
11 #include "stdafx.h"
12 #include "fred.h"
13 #include "ignoreordersdlg.h"
14 #include "hudsquadmsg.h"                                // need this for the menu stuff
15 #include "linklist.h"
16
17 #ifdef _DEBUG
18 #define new DEBUG_NEW
19 #undef THIS_FILE
20 static char THIS_FILE[] = __FILE__;
21 #endif
22
23 // super cool macro to make IDC_* names
24
25 // note: If you change this table at all, keep it in sync with version in HUDsquadmsg.cpp
26 fred_comm_order Fred_comm_orders[] = {
27         ATTACK_TARGET_ITEM, "Attack my target",
28         DISABLE_TARGET_ITEM, "Disable my target",
29         DISARM_TARGET_ITEM, "Disarm my target",
30         DISABLE_SUBSYSTEM_ITEM, "Destroy my subsystem",
31         PROTECT_TARGET_ITEM, "Protect my target",
32         IGNORE_TARGET_ITEM, "Ignore my target",
33         FORMATION_ITEM, "Form on my wing",
34         COVER_ME_ITEM, "Cover me",
35         ENGAGE_ENEMY_ITEM, "Engage enemy",
36         CAPTURE_TARGET_ITEM, "Capture my target",
37         REARM_REPAIR_ME_ITEM, "Rearm/repair me",
38         ABORT_REARM_REPAIR_ITEM, "Abort rearm repair",
39         DEPART_ITEM, "Depart",
40 };
41
42 int Fred_comm_orders_max = sizeof(Fred_comm_orders)/sizeof(fred_comm_order);
43
44 /////////////////////////////////////////////////////////////////////////////
45 // ignore_orders_dlg dialog
46
47 ignore_orders_dlg::ignore_orders_dlg(CWnd* pParent /*=NULL*/)
48         : CDialog(ignore_orders_dlg::IDD, pParent)
49 {
50         //{{AFX_DATA_INIT(ignore_orders_dlg)
51                 // NOTE: the ClassWizard will add member initialization here
52         //}}AFX_DATA_INIT
53 }
54
55 void ignore_orders_dlg::DoDataExchange(CDataExchange* pDX)
56 {
57         CDialog::DoDataExchange(pDX);
58         //{{AFX_DATA_MAP(ignore_orders_dlg)
59                 // NOTE: the ClassWizard will add DDX and DDV calls here
60         //}}AFX_DATA_MAP
61 }
62
63
64 BEGIN_MESSAGE_MAP(ignore_orders_dlg, CDialog)
65         //{{AFX_MSG_MAP(ignore_orders_dlg)
66         ON_BN_CLICKED(IDC_CHECK1, OnCheck1)
67         ON_BN_CLICKED(IDC_CHECK2, OnCheck2)
68         ON_BN_CLICKED(IDC_CHECK3, OnCheck3)
69         ON_BN_CLICKED(IDC_CHECK4, OnCheck4)
70         ON_BN_CLICKED(IDC_CHECK5, OnCheck5)
71         ON_BN_CLICKED(IDC_CHECK6, OnCheck6)
72         ON_BN_CLICKED(IDC_CHECK7, OnCheck7)
73         ON_BN_CLICKED(IDC_CHECK8, OnCheck8)
74         ON_BN_CLICKED(IDC_CHECK9, OnCheck9)
75         ON_BN_CLICKED(IDC_CHECK10, OnCheck10)
76         //}}AFX_MSG_MAP
77 END_MESSAGE_MAP()
78
79 /////////////////////////////////////////////////////////////////////////////
80 // ignore_orders_dlg message handlers
81
82 BOOL ignore_orders_dlg::OnInitDialog() 
83 {
84         int i, default_orders, last_bottom, orders_accepted;
85         RECT    window_size;
86         char buf[128];
87         object *objp;
88
89         CDialog::OnInitDialog();
90         
91         check_boxes[0].button = (CButton *)GetDlgItem( IDC_CHECK1 );
92         check_boxes[1].button = (CButton *)GetDlgItem( IDC_CHECK2 );
93         check_boxes[2].button = (CButton *)GetDlgItem( IDC_CHECK3 );
94         check_boxes[3].button = (CButton *)GetDlgItem( IDC_CHECK4 );
95         check_boxes[4].button = (CButton *)GetDlgItem( IDC_CHECK5 );
96         check_boxes[5].button = (CButton *)GetDlgItem( IDC_CHECK6 );
97         check_boxes[6].button = (CButton *)GetDlgItem( IDC_CHECK7 );
98         check_boxes[7].button = (CButton *)GetDlgItem( IDC_CHECK8 );
99         check_boxes[8].button = (CButton *)GetDlgItem( IDC_CHECK9 );
100         check_boxes[9].button = (CButton *)GetDlgItem( IDC_CHECK10 );
101
102         // change the labels on the check boxes to reflect the set of default
103         // orders for this ship
104         if ( m_ship >= 0 ) {
105                 default_orders = ship_get_default_orders_accepted( &Ship_info[Ships[m_ship].ship_info_index] );
106         } else {
107                 // we are doing multiple edit on ships.  We just need to get default orders for
108                 // the first marked ship since they'd better all be the same anyway!!!
109                 default_orders = 0;
110                 for ( objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
111                         if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
112                                 int these_orders;
113
114                                 these_orders = ship_get_default_orders_accepted( &Ship_info[Ships[objp->instance].ship_info_index] );
115                                 if ( default_orders == 0 )
116                                         default_orders = these_orders;
117                                 else if ( default_orders != these_orders )
118                                         Int3();
119                         }
120                 }
121
122         }
123
124         // set the checkboxes for the orders accepted
125         m_num_checks_active = 0;
126         for (i = 0; i < MAX_SHIP_ORDERS; i++ ) {
127                 if ( default_orders & Fred_comm_orders[i].value ) {
128                         Assert( m_num_checks_active < MAX_CHECKBOXES );
129                         check_boxes[m_num_checks_active].button->SetWindowText( Fred_comm_orders[i].menu_text );
130                         check_boxes[m_num_checks_active].id = Fred_comm_orders[i].value;
131                         m_num_checks_active++;
132                 }
133         }
134
135         // resize the dialog by shrinking the height by the number of checkboxes that
136         // we removed
137         GetWindowRect( &window_size );
138
139         // hide the rest of the dialog items
140         last_bottom = 0;
141         for ( i = MAX_CHECKBOXES - 1; i >= m_num_checks_active; i-- ) {
142                 RECT check_size;
143
144                 // get the size of the checkbox, then hide it.
145                 check_boxes[i].button->GetWindowRect( &check_size );
146                 check_boxes[i].button->ShowWindow(SW_HIDE);
147
148                 // shrink the size of the parent window by the size of the checkbox
149                 if ( last_bottom != 0 )
150                         window_size.bottom -= (last_bottom - check_size.bottom );
151
152                 last_bottom = check_size.bottom;
153
154         }
155
156         // call MoveWindow to resize the window
157         MoveWindow( &window_size, TRUE );
158
159         // set the check marks in the box based on orders_accepted valud in the ship structure(s)
160         if ( m_ship >= 0 ) {
161                 orders_accepted = Ships[m_ship].orders_accepted;
162                 for ( i = 0; i < m_num_checks_active; i++ ) {
163                         if ( check_boxes[i].id & orders_accepted )
164                                 check_boxes[i].button->SetCheck(1);
165                 }
166         } else {
167                 int first_time;
168
169                 first_time = 1;
170                 for ( objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
171                         if (((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) && (objp->flags & OF_MARKED)) {
172
173                                 // get the orders for this ship.  If a state is not set 
174                                 orders_accepted = Ships[objp->instance].orders_accepted;
175                                 if ( first_time ) {
176                                         for ( i = 0; i < m_num_checks_active; i++ ) {
177                                                 if ( check_boxes[i].id & orders_accepted )
178                                                         check_boxes[i].button->SetCheck(1);
179                                         }
180                                         first_time = 0;
181                                 } else {
182                                         for ( i = 0; i < m_num_checks_active; i++ ) {
183                                                 // see if the order matches the check box order
184                                                 if ( check_boxes[i].id & orders_accepted ) {
185                                                         // if it matches, if it is not already set, then it is indeterminate.
186                                                         if ( !check_boxes[i].button->GetCheck() )
187                                                                 check_boxes[i].button->SetCheck(2);
188                                                 } else {
189                                                         // if the order isn't active, and already set, mark as indeterminite.
190                                                         if ( check_boxes[i].button->GetCheck() )
191                                                                 check_boxes[i].button->SetCheck(2);
192                                                 }
193                                         }
194                                 }
195                         }
196                 }
197         }
198
199         // finally, set the title of the window to be something else.  We really aren't checking orders
200         // which will be ignore, but rather orders which will be accepted
201         sprintf(buf, "Player orders accepted" );
202         SetWindowText(buf);
203
204         return TRUE;  // return TRUE unless you set the focus to a control
205                       // EXCEPTION: OCX Property Pages should return FALSE
206 }
207
208 // for the OnOK function, we scan through the list of checkboxes, and reset the ship's orders accepted
209 // variable based on the state of the checkboxes
210 void ignore_orders_dlg::OnOK() 
211 {
212         int orders_accepted, i;
213         object *objp;
214
215         // clear out the orders, then set the bits according to which check boxes are set
216         if ( m_ship >= 0 ) {
217                 orders_accepted = 0;
218                 for ( i = 0; i < m_num_checks_active; i++ ) {
219                         if ( check_boxes[i].button->GetCheck() )
220                                 orders_accepted |= check_boxes[i].id;
221                 }
222                 Ships[m_ship].orders_accepted = orders_accepted;
223         } else {
224                 for ( objp = GET_FIRST(&obj_used_list); objp != END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
225                         if (((objp->type == OBJ_SHIP) || (objp->type == OBJ_START)) && (objp->flags & OF_MARKED)) {
226                                 Ships[objp->instance].orders_accepted = 0;
227                                 for ( i = 0; i < m_num_checks_active; i++ ) {
228                                         int box_value;
229
230                                         box_value = check_boxes[i].button->GetCheck();
231                                         // get the status of the checkbox -- if in the indeterminite state, then
232                                         // skip it
233                                         if ( box_value == 2 )
234                                                 continue;
235
236                                         // if the button is set, then set the bit, otherwise, clear the bit
237                                         if ( box_value == 1 )
238                                                 Ships[objp->instance].orders_accepted |= check_boxes[i].id;
239                                         else
240                                                 Ships[objp->instance].orders_accepted &= ~(check_boxes[i].id);
241                                 }
242                         }
243                 }
244         }
245         
246         CDialog::OnOK();
247 }
248
249 // stupid routines to deal with the tri-state values of the checkboxes
250 void ignore_orders_dlg::OnCheck1() 
251 {
252         CButton *button;
253
254         button = (CButton *)GetDlgItem(IDC_CHECK1);
255         if (button->GetCheck() == 1)
256                 button->SetCheck(0);
257         else
258                 button->SetCheck(1);
259 }
260
261 void ignore_orders_dlg::OnCheck2() 
262 {
263         CButton *button;
264
265         button = (CButton *)GetDlgItem(IDC_CHECK2);
266         if (button->GetCheck() == 1)
267                 button->SetCheck(0);
268         else
269                 button->SetCheck(1);
270 }
271
272 void ignore_orders_dlg::OnCheck3() 
273 {
274         CButton *button;
275
276         button = (CButton *)GetDlgItem(IDC_CHECK3);
277         if (button->GetCheck() == 1)
278                 button->SetCheck(0);
279         else
280                 button->SetCheck(1);
281 }
282
283 void ignore_orders_dlg::OnCheck4() 
284 {
285         CButton *button;
286
287         button = (CButton *)GetDlgItem(IDC_CHECK4);
288         if (button->GetCheck() == 1)
289                 button->SetCheck(0);
290         else
291                 button->SetCheck(1);
292 }
293
294 void ignore_orders_dlg::OnCheck5() 
295 {
296         CButton *button;
297
298         button = (CButton *)GetDlgItem(IDC_CHECK5);
299         if (button->GetCheck() == 1)
300                 button->SetCheck(0);
301         else
302                 button->SetCheck(1);
303 }
304
305 void ignore_orders_dlg::OnCheck6() 
306 {
307         CButton *button;
308
309         button = (CButton *)GetDlgItem(IDC_CHECK6);
310         if (button->GetCheck() == 1)
311                 button->SetCheck(0);
312         else
313                 button->SetCheck(1);
314 }
315
316 void ignore_orders_dlg::OnCheck7() 
317 {
318         CButton *button;
319
320         button = (CButton *)GetDlgItem(IDC_CHECK7);
321         if (button->GetCheck() == 1)
322                 button->SetCheck(0);
323         else
324                 button->SetCheck(1);
325 }
326
327 void ignore_orders_dlg::OnCheck8() 
328 {
329         CButton *button;
330
331         button = (CButton *)GetDlgItem(IDC_CHECK8);
332         if (button->GetCheck() == 1)
333                 button->SetCheck(0);
334         else
335                 button->SetCheck(1);
336 }
337
338 void ignore_orders_dlg::OnCheck9() 
339 {
340         CButton *button;
341
342         button = (CButton *)GetDlgItem(IDC_CHECK9);
343         if (button->GetCheck() == 1)
344                 button->SetCheck(0);
345         else
346                 button->SetCheck(1);
347 }
348
349 void ignore_orders_dlg::OnCheck10() 
350 {
351         CButton *button;
352
353         button = (CButton *)GetDlgItem(IDC_CHECK10);
354         if (button->GetCheck() == 1)
355                 button->SetCheck(0);
356         else
357                 button->SetCheck(1);
358 }