2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/fred2/ShipGoalsDlg.cpp $
15 * Initial orders editor dialog box handling code. This dialog is used for both
16 * ship and wing initial orders, and can support more if need be without modification.
19 * Revision 1.3 2002/06/09 04:41:17 relnev
20 * added copyright header
22 * Revision 1.2 2002/05/07 03:16:44 theoddone33
23 * The Great Newline Fix
25 * Revision 1.1.1.1 2002/05/03 03:28:08 root
29 * 4 3/26/99 4:49p Dave
30 * Made cruisers able to dock with stuff. Made docking points and paths
33 * 3 3/25/99 3:32p Johnson
34 * HACK: Allow Mycerinus to dock
36 * 2 10/07/98 6:28p Dave
37 * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
38 * Fred. Globalized mission and campaign file extensions. Removed Silent
39 * Threat specific code.
41 * 1 10/07/98 3:01p Dave
43 * 1 10/07/98 3:00p Dave
45 * 57 7/06/98 5:12p Hoffoss
46 * Fixed bug where 3-5th orders don't update data listing when object
49 * 56 5/21/98 12:58a Hoffoss
50 * Fixed warnings optimized build turned up.
52 * 55 4/06/98 11:34a Hoffoss
53 * Fixed bug caused by change in max ai goals. Should be able to handle
54 * anything from 0 to 10 ai goals now (i.e. it's more flexible now).
56 * 54 11/05/97 4:43p Allender
57 * reworked medal/rank system to read all data from tables. Made Fred
58 * read medals.tbl. Changed ai-warp to ai-warp-out which doesn't require
59 * waypoint for activation
61 * 53 10/22/97 3:15p Hoffoss
62 * Fixed ai-stay-still initial order to use waypoints instead of waypoint
65 * 52 10/22/97 1:58p Hoffoss
66 * Added support for AI_GOALS_PLAY_DEAD and changed AI_GOALS_STAY_STILL
69 * 51 10/10/97 5:03p Allender
70 * started work on ai-stay-still
72 * 50 9/18/97 11:28a Duncan
73 * Fixed bug with player objects having wrong name.
75 * 49 9/16/97 9:41p Hoffoss
76 * Changed Fred code around to stop using Parse_player structure for
77 * player information, and use actual ships instead.
79 * 48 9/09/97 3:39p Sandeep
80 * warning level 4 bugs
82 * 47 9/02/97 5:10p Johnson
83 * Fixed bug with wing initial orders available to select from.
85 * 46 8/26/97 4:18p Hoffoss
86 * Added error checking to initial orders dialog when ok is clicked.
88 * 45 8/19/97 11:59a Duncan
89 * Fixed bug in initial orders set_item().
91 * 44 8/16/97 4:51p Hoffoss
92 * Fixed bugs with wing deletion and removing ships from a wing.
94 * 43 8/15/97 5:14p Hoffoss
95 * Completely changed around how initial orders dialog worked. It's
98 * 42 8/14/97 7:07p Hoffoss
99 * Changed "guard ship" to "guard", since it can be used with wings now as
102 * 41 8/10/97 4:41p Hoffoss
103 * Fixed bugs with docking initial order.
105 * 40 8/05/97 10:10p Hoffoss
106 * Made attack and guard orders handle both ships and wings as targets.
108 * 39 8/01/97 12:21p Jasen
109 * Fixed bug with docking order (in iinitial orders) where original dockee
110 * was deleted, and so not found when looked up.
112 * 38 7/30/97 12:31p Hoffoss
113 * Made improvements to ship goals editor (initial orders) to disallow
116 * 37 7/25/97 4:30p Hoffoss
117 * Changes to ship lookup to include player ships.
119 * 36 7/24/97 4:55p Allender
120 * added ai-evade-ship to fred and to Freespace
122 * 35 7/22/97 3:40p Allender
123 * Changed the way that attacking subsystem works (for initial orders).
124 * The code was behaving two different ways. Orders are now model
125 * specific as per which subsystem to attack.
127 * 34 7/17/97 4:23p Allender
128 * ai-guard-wing now in both Fred and Freespace
130 * 33 7/09/97 1:56p Jasen
131 * Added new case to data mode checkunder save item.
133 * 32 6/11/97 2:13p Hoffoss
134 * Fixed bug in initial order initialization, and made subsystem combo box
135 * use ship specific subsystems.
137 * 31 6/04/97 12:00a Allender
138 * added disarm and disable as initial order options
140 * 30 5/30/97 4:50p Hoffoss
141 * Added code to allow marked ship editing of data in child dialogs of
142 * ship editor dialog.
144 * 29 5/07/97 1:32p Allender
145 * fix bug from previous checkin where undock orders were not persistent
147 * 28 5/07/97 1:08p Allender
148 * make undock initial order only accept a priority
150 * 27 4/03/97 3:18p Allender
152 * 26 3/31/97 6:07p Hoffoss
153 * Fixed several errors, including BG editor not graying fields, BG editor
154 * not updating image when changed, Removed obsolete data from Weapon
155 * editor, priority not being saved when missions saved, priority not
156 * editable in initial orders editor.
158 * 25 3/28/97 3:19p Hoffoss
159 * Added chase-any goal to initial orders.
161 * 24 3/21/97 4:04p Bernal
162 * fixed crash when initial orders references illegal objects. (Jason)
164 * 23 3/21/97 10:29a Hoffoss
165 * forced negative priorities to 50
167 * 22 3/19/97 4:53p Hoffoss
168 * fixed bug with unused fields not being cleared.
170 * 21 3/13/97 12:20p Hoffoss
171 * fixed bug in docking point specification of initial orders dialog.
173 * 20 3/10/97 6:43p Hoffoss
174 * Standardized docking goal usage by fred to use names instead of
177 * 19 3/10/97 5:37p Hoffoss
178 * fixed bug in dock goal selection.
180 * 18 3/10/97 12:54p Hoffoss
181 * Added drop down combo box to toolbar and fixed compiling errors Mark
182 * (maybe Mike?) introduced to code.
184 * 17 3/04/97 12:52p Allender
185 * docking styff. Added dock type to docking structure in model code.
186 * Renamed structure member in ai_goals. Temporary checkin. (i.e.
187 * rearming will use rearm dock points)
189 * 16 3/03/97 4:32p Hoffoss
190 * Initial orders supports new docking stuff Allender added.
192 * 15 2/27/97 3:15p Allender
193 * major wing structure enhancement. simplified wing code. All around
194 * better wing support
196 * 14 2/26/97 2:45p Hoffoss
197 * Initial orders dialog now only allows 89 as a max on priority.
199 * 13 2/21/97 5:34p Hoffoss
200 * Added extensive modification detection and fixed a bug in initial
203 * 12 2/17/97 5:28p Hoffoss
204 * Checked RCS headers, added them were missing, changing description to
205 * something better, etc where needed.
212 #include "shipgoalsdlg.h"
214 #include "linklist.h"
215 #include "management.h"
218 #include "fredview.h"
220 #define TYPE_PATH 0x1000
221 #define TYPE_SHIP 0x2000
222 #define TYPE_PLAYER 0x3000
223 #define TYPE_WING 0x4000
224 #define TYPE_WAYPOINT 0x5000
225 #define TYPE_MASK 0xf000
226 #define DATA_MASK 0x0fff
229 #define new DEBUG_NEW
231 static char THIS_FILE[] = __FILE__;
234 /////////////////////////////////////////////////////////////////////////////
235 // ShipGoalsDlg dialog
237 ShipGoalsDlg::ShipGoalsDlg(CWnd* pParent /*=NULL*/)
238 : CDialog(ShipGoalsDlg::IDD, pParent)
242 for (i=0; i<ED_MAX_GOALS; i++) {
251 //{{AFX_DATA_INIT(ShipGoalsDlg)
254 self_ship = self_wing = -1;
257 void ShipGoalsDlg::DoDataExchange(CDataExchange* pDX)
259 CDialog::DoDataExchange(pDX);
260 //{{AFX_DATA_MAP(ShipGoalsDlg)
263 DDX_CBIndex(pDX, IDC_BEHAVIOR1, m_behavior[0]);
264 DDX_CBIndex(pDX, IDC_BEHAVIOR2, m_behavior[1]);
265 DDX_CBIndex(pDX, IDC_BEHAVIOR3, m_behavior[2]);
266 DDX_CBIndex(pDX, IDC_BEHAVIOR4, m_behavior[3]);
267 DDX_CBIndex(pDX, IDC_BEHAVIOR5, m_behavior[4]);
268 DDX_CBIndex(pDX, IDC_BEHAVIOR6, m_behavior[5]);
269 DDX_CBIndex(pDX, IDC_BEHAVIOR7, m_behavior[6]);
270 DDX_CBIndex(pDX, IDC_BEHAVIOR8, m_behavior[7]);
271 DDX_CBIndex(pDX, IDC_BEHAVIOR9, m_behavior[8]);
272 DDX_CBIndex(pDX, IDC_BEHAVIOR10, m_behavior[9]);
274 DDX_CBIndex(pDX, IDC_OBJECT1, m_object[0]);
275 DDX_CBIndex(pDX, IDC_OBJECT2, m_object[1]);
276 DDX_CBIndex(pDX, IDC_OBJECT3, m_object[2]);
277 DDX_CBIndex(pDX, IDC_OBJECT4, m_object[3]);
278 DDX_CBIndex(pDX, IDC_OBJECT5, m_object[4]);
279 DDX_CBIndex(pDX, IDC_OBJECT6, m_object[5]);
280 DDX_CBIndex(pDX, IDC_OBJECT7, m_object[6]);
281 DDX_CBIndex(pDX, IDC_OBJECT8, m_object[7]);
282 DDX_CBIndex(pDX, IDC_OBJECT9, m_object[8]);
283 DDX_CBIndex(pDX, IDC_OBJECT10, m_object[9]);
285 DDX_Text(pDX, IDC_PRIORITY1, m_priority[0]);
286 DDV_MinMaxInt(pDX, m_priority[0], 0, 89);
287 DDX_Text(pDX, IDC_PRIORITY2, m_priority[1]);
288 DDV_MinMaxInt(pDX, m_priority[1], 0, 89);
289 DDX_Text(pDX, IDC_PRIORITY3, m_priority[2]);
290 DDV_MinMaxInt(pDX, m_priority[2], 0, 89);
291 DDX_Text(pDX, IDC_PRIORITY4, m_priority[3]);
292 DDV_MinMaxInt(pDX, m_priority[3], 0, 89);
293 DDX_Text(pDX, IDC_PRIORITY5, m_priority[4]);
294 DDV_MinMaxInt(pDX, m_priority[4], 0, 89);
295 DDX_Text(pDX, IDC_PRIORITY6, m_priority[5]);
296 DDV_MinMaxInt(pDX, m_priority[5], 0, 89);
297 DDX_Text(pDX, IDC_PRIORITY7, m_priority[6]);
298 DDV_MinMaxInt(pDX, m_priority[6], 0, 89);
299 DDX_Text(pDX, IDC_PRIORITY8, m_priority[7]);
300 DDV_MinMaxInt(pDX, m_priority[7], 0, 89);
301 DDX_Text(pDX, IDC_PRIORITY9, m_priority[8]);
302 DDV_MinMaxInt(pDX, m_priority[8], 0, 89);
303 DDX_Text(pDX, IDC_PRIORITY10, m_priority[9]);
304 DDV_MinMaxInt(pDX, m_priority[9], 0, 89);
306 DDX_CBIndex(pDX, IDC_SUBSYSTEM1, m_subsys[0]);
307 DDX_CBIndex(pDX, IDC_SUBSYSTEM2, m_subsys[1]);
308 DDX_CBIndex(pDX, IDC_SUBSYSTEM3, m_subsys[2]);
309 DDX_CBIndex(pDX, IDC_SUBSYSTEM4, m_subsys[3]);
310 DDX_CBIndex(pDX, IDC_SUBSYSTEM5, m_subsys[4]);
311 DDX_CBIndex(pDX, IDC_SUBSYSTEM6, m_subsys[5]);
312 DDX_CBIndex(pDX, IDC_SUBSYSTEM7, m_subsys[6]);
313 DDX_CBIndex(pDX, IDC_SUBSYSTEM8, m_subsys[7]);
314 DDX_CBIndex(pDX, IDC_SUBSYSTEM9, m_subsys[8]);
315 DDX_CBIndex(pDX, IDC_SUBSYSTEM10, m_subsys[9]);
317 DDX_CBIndex(pDX, IDC_DOCK1, m_dock2[0]);
318 DDX_CBIndex(pDX, IDC_DOCK2, m_dock2[1]);
319 DDX_CBIndex(pDX, IDC_DOCK3, m_dock2[2]);
320 DDX_CBIndex(pDX, IDC_DOCK4, m_dock2[3]);
321 DDX_CBIndex(pDX, IDC_DOCK5, m_dock2[4]);
322 DDX_CBIndex(pDX, IDC_DOCK6, m_dock2[5]);
323 DDX_CBIndex(pDX, IDC_DOCK7, m_dock2[6]);
324 DDX_CBIndex(pDX, IDC_DOCK8, m_dock2[7]);
325 DDX_CBIndex(pDX, IDC_DOCK9, m_dock2[8]);
326 DDX_CBIndex(pDX, IDC_DOCK10, m_dock2[9]);
329 BEGIN_MESSAGE_MAP(ShipGoalsDlg, CDialog)
330 //{{AFX_MSG_MAP(ShipGoalsDlg)
331 ON_CBN_SELCHANGE(IDC_BEHAVIOR1, OnSelchangeBehavior1)
332 ON_CBN_SELCHANGE(IDC_BEHAVIOR2, OnSelchangeBehavior2)
333 ON_CBN_SELCHANGE(IDC_BEHAVIOR3, OnSelchangeBehavior3)
334 ON_CBN_SELCHANGE(IDC_BEHAVIOR4, OnSelchangeBehavior4)
335 ON_CBN_SELCHANGE(IDC_BEHAVIOR5, OnSelchangeBehavior5)
336 ON_CBN_SELCHANGE(IDC_BEHAVIOR6, OnSelchangeBehavior6)
337 ON_CBN_SELCHANGE(IDC_BEHAVIOR7, OnSelchangeBehavior7)
338 ON_CBN_SELCHANGE(IDC_BEHAVIOR8, OnSelchangeBehavior8)
339 ON_CBN_SELCHANGE(IDC_BEHAVIOR9, OnSelchangeBehavior9)
340 ON_CBN_SELCHANGE(IDC_BEHAVIOR10, OnSelchangeBehavior10)
341 ON_CBN_SELCHANGE(IDC_OBJECT1, OnSelchangeObject1)
342 ON_CBN_SELCHANGE(IDC_OBJECT2, OnSelchangeObject2)
343 ON_CBN_SELCHANGE(IDC_OBJECT3, OnSelchangeObject3)
344 ON_CBN_SELCHANGE(IDC_OBJECT4, OnSelchangeObject4)
345 ON_CBN_SELCHANGE(IDC_OBJECT5, OnSelchangeObject5)
346 ON_CBN_SELCHANGE(IDC_OBJECT6, OnSelchangeObject6)
347 ON_CBN_SELCHANGE(IDC_OBJECT7, OnSelchangeObject7)
348 ON_CBN_SELCHANGE(IDC_OBJECT8, OnSelchangeObject8)
349 ON_CBN_SELCHANGE(IDC_OBJECT9, OnSelchangeObject9)
350 ON_CBN_SELCHANGE(IDC_OBJECT10, OnSelchangeObject10)
354 /////////////////////////////////////////////////////////////////////////////
355 // ShipGoalsDlg message handlers
357 BOOL ShipGoalsDlg::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
359 return CDialog::Create(IDD, &Ship_editor_dialog);
362 BOOL ShipGoalsDlg::OnInitDialog()
364 int i, j, z, valid[99];
367 // set up pointers to all the combo boxes to simplify things a lot
368 m_behavior_box[0] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR1);
369 m_behavior_box[1] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR2);
370 m_behavior_box[2] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR3);
371 m_behavior_box[3] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR4);
372 m_behavior_box[4] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR5);
373 m_behavior_box[5] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR6);
374 m_behavior_box[6] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR7);
375 m_behavior_box[7] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR8);
376 m_behavior_box[8] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR9);
377 m_behavior_box[9] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR10);
379 m_object_box[0] = (CComboBox *) GetDlgItem(IDC_OBJECT1);
380 m_object_box[1] = (CComboBox *) GetDlgItem(IDC_OBJECT2);
381 m_object_box[2] = (CComboBox *) GetDlgItem(IDC_OBJECT3);
382 m_object_box[3] = (CComboBox *) GetDlgItem(IDC_OBJECT4);
383 m_object_box[4] = (CComboBox *) GetDlgItem(IDC_OBJECT5);
384 m_object_box[5] = (CComboBox *) GetDlgItem(IDC_OBJECT6);
385 m_object_box[6] = (CComboBox *) GetDlgItem(IDC_OBJECT7);
386 m_object_box[7] = (CComboBox *) GetDlgItem(IDC_OBJECT8);
387 m_object_box[8] = (CComboBox *) GetDlgItem(IDC_OBJECT9);
388 m_object_box[9] = (CComboBox *) GetDlgItem(IDC_OBJECT10);
390 m_subsys_box[0] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM1);
391 m_subsys_box[1] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM2);
392 m_subsys_box[2] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM3);
393 m_subsys_box[3] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM4);
394 m_subsys_box[4] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM5);
395 m_subsys_box[5] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM6);
396 m_subsys_box[6] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM7);
397 m_subsys_box[7] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM8);
398 m_subsys_box[8] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM9);
399 m_subsys_box[9] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM10);
401 m_dock2_box[0] = (CComboBox *) GetDlgItem(IDC_DOCK1);
402 m_dock2_box[1] = (CComboBox *) GetDlgItem(IDC_DOCK2);
403 m_dock2_box[2] = (CComboBox *) GetDlgItem(IDC_DOCK3);
404 m_dock2_box[3] = (CComboBox *) GetDlgItem(IDC_DOCK4);
405 m_dock2_box[4] = (CComboBox *) GetDlgItem(IDC_DOCK5);
406 m_dock2_box[5] = (CComboBox *) GetDlgItem(IDC_DOCK6);
407 m_dock2_box[6] = (CComboBox *) GetDlgItem(IDC_DOCK7);
408 m_dock2_box[7] = (CComboBox *) GetDlgItem(IDC_DOCK8);
409 m_dock2_box[8] = (CComboBox *) GetDlgItem(IDC_DOCK9);
410 m_dock2_box[9] = (CComboBox *) GetDlgItem(IDC_DOCK10);
412 m_priority_box[0] = (CComboBox *) GetDlgItem(IDC_PRIORITY1);
413 m_priority_box[1] = (CComboBox *) GetDlgItem(IDC_PRIORITY2);
414 m_priority_box[2] = (CComboBox *) GetDlgItem(IDC_PRIORITY3);
415 m_priority_box[3] = (CComboBox *) GetDlgItem(IDC_PRIORITY4);
416 m_priority_box[4] = (CComboBox *) GetDlgItem(IDC_PRIORITY5);
417 m_priority_box[5] = (CComboBox *) GetDlgItem(IDC_PRIORITY6);
418 m_priority_box[6] = (CComboBox *) GetDlgItem(IDC_PRIORITY7);
419 m_priority_box[7] = (CComboBox *) GetDlgItem(IDC_PRIORITY8);
420 m_priority_box[8] = (CComboBox *) GetDlgItem(IDC_PRIORITY9);
421 m_priority_box[9] = (CComboBox *) GetDlgItem(IDC_PRIORITY10);
423 // start off with all goals available
424 for (i=0; i<Ai_goal_list_size; i++)
427 // disallow orders if they aren't allowed because of ship type
428 if (self_ship >= 0) { // editing orders for just one ship
429 for (i=0; i<Ai_goal_list_size; i++){
430 if (!(ai_query_goal_valid(self_ship, Ai_goal_list[i].def))){
434 } else if (self_wing >= 0) { // editing orders for just one wing
435 for (i=0; i<Wings[self_wing].wave_count; i++){
436 for (j=0; j<Ai_goal_list_size; j++){
437 if (!ai_query_goal_valid(Wings[self_wing].ship_index[i], Ai_goal_list[j].def)){
443 for (i=0; i<Ai_goal_list_size; i++){
444 if (Ai_goal_list[i].def == AI_GOAL_DOCK){ // a whole wing can't dock with one object..
448 } else { // editing orders for all marked ships
449 ptr = GET_FIRST(&obj_used_list);
450 while (ptr != END_OF_LIST(&obj_used_list)) {
451 if ((ptr->type == OBJ_SHIP) && (ptr->flags & OF_MARKED)){
452 for (i=0; i<Ai_goal_list_size; i++){
453 if (!ai_query_goal_valid(ptr->instance, Ai_goal_list[i].def)){
463 for (i=0; i<MAX_WAYPOINT_LISTS; i++){
464 if (Waypoint_lists[i].count){
469 if (i == MAX_WAYPOINT_LISTS){
470 for (i=0; i<Ai_goal_list_size; i++){
471 switch (Ai_goal_list[i].def) {
472 case AI_GOAL_WAYPOINTS:
473 case AI_GOAL_WAYPOINTS_ONCE:
481 ptr = GET_FIRST(&obj_used_list);
482 while (ptr != END_OF_LIST(&obj_used_list)) {
483 if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) {
486 if ((self_ship > 0) && (self_ship != i) && ship_docking_valid(self_ship, i)){
494 for (i=0; i<Ai_goal_list_size; i++){
495 if (Ai_goal_list[i].def == AI_GOAL_DOCK){
501 // initialize the behavior boxes (they remain constant) and initialize each goal's data
502 for (i=0; i<ED_MAX_GOALS; i++) {
503 m_behavior_box[i] -> ResetContent();
504 z = m_behavior_box[i] -> AddString("None");
505 m_behavior_box[i] -> SetItemData(z, (DWORD) AI_GOAL_NONE);
506 for (j=0; j<Ai_goal_list_size; j++){
508 z = m_behavior_box[i] -> AddString(Ai_goal_list[j].name);
509 m_behavior_box[i] -> SetItemData(z, (DWORD) Ai_goal_list[j].def);
515 initialize(Ai_info[Ships[self_ship].ai_index].goals, self_ship);
516 } else if (self_wing >= 0){
517 initialize(Wings[self_wing].ai_goals);
522 for (i=0; i<ED_MAX_GOALS; i++){
526 CDialog::OnInitDialog();
528 // restrict spin controls to a range of 0 - 89
529 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN1)) -> SetRange(0, 89);
530 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN2)) -> SetRange(0, 89);
531 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN3)) -> SetRange(0, 89);
532 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN4)) -> SetRange(0, 89);
533 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN5)) -> SetRange(0, 89);
534 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN6)) -> SetRange(0, 89);
535 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN7)) -> SetRange(0, 89);
536 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN8)) -> SetRange(0, 89);
537 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN9)) -> SetRange(0, 89);
538 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN10)) -> SetRange(0, 89);
543 void ShipGoalsDlg::initialize_multi()
547 int behavior[ED_MAX_GOALS];
548 int priority[ED_MAX_GOALS];
549 int subsys[ED_MAX_GOALS];
550 int dock2[ED_MAX_GOALS];
551 int data[ED_MAX_GOALS];
553 ptr = GET_FIRST(&obj_used_list);
554 while (ptr != END_OF_LIST(&obj_used_list)) {
555 if ((ptr->type == OBJ_SHIP) && (ptr->flags & OF_MARKED)) {
556 initialize(Ai_info[Ships[ptr->instance].ai_index].goals, ptr->instance);
559 for (i=0; i<ED_MAX_GOALS; i++) {
560 behavior[i] = m_behavior[i];
561 priority[i] = m_priority[i];
562 subsys[i] = m_subsys[i];
563 dock2[i] = m_dock2[i];
568 for (i=0; i<ED_MAX_GOALS; i++) {
569 if (behavior[i] != m_behavior[i]) {
574 if (data[i] != m_data[i]) {
580 if (priority[i] != m_priority[i]){
583 if (subsys[i] != m_subsys[i]){
586 if (dock2[i] != m_dock2[i]){
597 for (i=0; i<ED_MAX_GOALS; i++) {
598 m_behavior[i] = behavior[i];
599 m_priority[i] = priority[i];
600 m_subsys[i] = subsys[i];
601 m_dock2[i] = dock2[i];
606 // perform one-time initialization of data from the goals struct.
607 void ShipGoalsDlg::initialize(ai_goal *goals, int ship)
609 int i, item, num, inst, flag, mode;
613 for (item=0; item<ED_MAX_GOALS; item++) {
616 m_priority[item] = 0;
619 if (item < MAX_AI_GOALS) {
620 m_priority[item] = goalp[item].priority;
621 mode = goalp[item].ai_mode;
624 if (m_priority[item] < 0 || m_priority[item] > 89){
625 m_priority[item] = 50;
628 m_behavior[item] = 0;
629 if (mode != AI_GOAL_NONE) {
630 i = m_behavior_box[item] -> GetCount();
632 if (mode & (m_behavior_box[item]->GetItemData(i))) {
633 m_behavior[item] = i;
641 case AI_GOAL_CHASE_ANY:
643 case AI_GOAL_KEEP_SAFE_DISTANCE:
644 case AI_GOAL_PLAY_DEAD:
648 case AI_GOAL_STAY_STILL:
649 flag = 9; // target is a ship or a waypoint
654 case AI_GOAL_DISABLE_SHIP:
655 case AI_GOAL_DISARM_SHIP:
657 case AI_GOAL_EVADE_SHIP:
658 case AI_GOAL_STAY_NEAR_SHIP:
661 case AI_GOAL_WAYPOINTS:
662 case AI_GOAL_WAYPOINTS_ONCE:
663 flag = 4; // target is a waypoint
666 case AI_GOAL_DESTROY_SUBSYSTEM:
667 num = ship_name_lookup(goalp[item].ship_name, 1);
669 m_subsys[item] = ship_get_subsys_index(&Ships[num], goalp[item].docker.name, 1);
675 num = get_docking_list(Ships[ship].modelnum);
676 for (i=0; i<num; i++) {
677 SDL_assert(Docking_bay_list[i]);
678 if (!stricmp(goalp[item].docker.name, Docking_bay_list[i])) {
686 case AI_GOAL_CHASE_WING:
687 case AI_GOAL_GUARD_WING:
688 flag = 2; // target is a wing
696 ptr = GET_FIRST(&obj_used_list);
697 while (ptr != END_OF_LIST(&obj_used_list)) {
698 if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) {
699 inst = ptr->instance;
700 if (ptr->type == OBJ_SHIP) {
701 SDL_assert(inst >= 0 && inst < MAX_SHIPS);
702 if (!stricmp(goalp[item].ship_name, Ships[inst].ship_name)) {
703 m_data[item] = inst | TYPE_SHIP;
708 SDL_assert(inst >= 0 && inst < MAX_SHIPS);
709 if (!stricmp(goalp[item].ship_name, Ships[inst].ship_name)) {
710 m_data[item] = inst | TYPE_PLAYER;
721 for (i=0; i<MAX_WINGS; i++)
722 if (Wings[i].wave_count) {
723 if (!stricmp(goalp[item].ship_name, Wings[i].name)) {
724 m_data[item] = i | TYPE_WING;
730 if (flag & 0x4) { // data is a waypoint path name
731 for (i=0; i<Num_waypoint_lists; i++)
732 if (!stricmp(goalp[item].ship_name, Waypoint_lists[i].name)) {
733 m_data[item] = i | TYPE_PATH;
738 if (flag & 0x8) { // data is a waypoint name
739 i = waypoint_lookup(goalp[item].ship_name);
741 m_data[item] = i | TYPE_WAYPOINT;
748 num = get_docking_list(Ships[m_data[item] & DATA_MASK].modelnum);
749 for (i=0; i<num; i++) {
750 SDL_assert(Docking_bay_list[i]);
751 SDL_assert(goalp[item].dockee.name);
752 SDL_assert(goalp[item].dockee.index != -1);
753 if (!stricmp(goalp[item].dockee.name, Docking_bay_list[i])) {
763 // SDL_assert(m_data[item]);
767 void ShipGoalsDlg::set_item(int item, int init)
769 int i, t, z, num, inst, mode;
775 if (item >= MAX_AI_GOALS)
776 m_behavior_box[item] -> EnableWindow(FALSE);
778 SDL_assert(item >= 0 && item < ED_MAX_GOALS);
779 m_object_box[item] -> ResetContent();
780 if (m_behavior[item] < 1) {
781 m_object_box[item] -> EnableWindow(FALSE);
782 m_subsys_box[item] -> EnableWindow(FALSE);
783 m_dock2_box[item] -> EnableWindow(FALSE);
784 m_priority_box[item] -> EnableWindow(FALSE);
790 mode = m_behavior_box[item] -> GetItemData(m_behavior[item]);
791 m_priority_box[item] -> EnableWindow(TRUE);
792 if ((mode == AI_GOAL_CHASE_ANY) || (mode == AI_GOAL_UNDOCK) || (mode == AI_GOAL_KEEP_SAFE_DISTANCE) || (mode == AI_GOAL_PLAY_DEAD) || (mode == AI_GOAL_WARP) ) {
793 m_object_box[item] -> EnableWindow(FALSE);
794 m_subsys_box[item] -> EnableWindow(FALSE);
795 m_dock2_box[item] -> EnableWindow(FALSE);
801 m_object_box[item] -> EnableWindow(TRUE);
804 case AI_GOAL_WAYPOINTS:
805 case AI_GOAL_WAYPOINTS_ONCE:
807 for (i=0; i<MAX_WAYPOINT_LISTS; i++)
808 if (Waypoint_lists[i].count) {
809 z = m_object_box[item] -> AddString(Waypoint_lists[i].name);
810 m_object_box[item] -> SetItemData(z, i | TYPE_PATH);
811 if (init && (m_data[item] == (i | TYPE_PATH)))
817 case AI_GOAL_STAY_STILL:
818 ptr = GET_FIRST(&obj_used_list);
819 while (ptr != END_OF_LIST(&obj_used_list)) {
820 if (ptr->type == OBJ_WAYPOINT) {
822 z = m_object_box[item] -> AddString(object_name(OBJ_INDEX(ptr)));
823 m_object_box[item] -> SetItemData(z, OBJ_INDEX(ptr) | TYPE_WAYPOINT);
824 if (init && (m_data[item] == (OBJ_INDEX(ptr) | TYPE_WAYPOINT)))
835 case AI_GOAL_DESTROY_SUBSYSTEM:
836 case AI_GOAL_CHASE | AI_GOAL_CHASE_WING:
838 case AI_GOAL_GUARD | AI_GOAL_GUARD_WING:
839 case AI_GOAL_DISABLE_SHIP:
840 case AI_GOAL_DISARM_SHIP:
841 case AI_GOAL_EVADE_SHIP:
843 case AI_GOAL_STAY_NEAR_SHIP:
844 case AI_GOAL_STAY_STILL:
845 ptr = GET_FIRST(&obj_used_list);
846 while (ptr != END_OF_LIST(&obj_used_list)) {
847 if (ptr->type == OBJ_SHIP || ptr->type == OBJ_START) {
848 inst = ptr->instance;
849 if (ptr->type == OBJ_SHIP)
854 SDL_assert(inst >= 0 && inst < MAX_SHIPS);
855 // remove all marked ships from list
856 if (!goalp && (ptr->flags & OF_MARKED))
859 // when docking, remove invalid dock targets
860 else if (mode == AI_GOAL_DOCK) {
861 if (self_ship < 0 || !ship_docking_valid(self_ship, inst))
865 // disallow ship being it's own target
866 if (inst >= 0 && inst != self_ship) {
867 z = m_object_box[item] -> AddString(Ships[inst].ship_name);
868 m_object_box[item] -> SetItemData(z, inst | t);
869 if (init && (m_data[item] == (inst | t)))
881 case AI_GOAL_CHASE | AI_GOAL_CHASE_WING:
882 case AI_GOAL_GUARD | AI_GOAL_GUARD_WING:
883 for (i=0; i<MAX_WINGS; i++)
884 if (Wings[i].wave_count && i != self_wing) {
885 z = m_object_box[item] -> AddString(Wings[i].name);
886 m_object_box[item] -> SetItemData(z, i | TYPE_WING);
887 if (init && (m_data[item] == (i | TYPE_WING)))
894 if (mode == AI_GOAL_DESTROY_SUBSYSTEM) {
895 m_subsys_box[item] -> EnableWindow(TRUE);
896 m_dock2_box[item] -> EnableWindow(FALSE);
899 if (!m_behavior[item])
900 set_item(item, init);
902 } else if (mode == AI_GOAL_DOCK) {
903 num = get_docking_list(Ships[cur_ship].modelnum);
904 m_subsys_box[item] -> EnableWindow(TRUE);
905 m_subsys_box[item] -> ResetContent();
906 for (i=0; i<num; i++) {
907 SDL_assert(Docking_bay_list[i]);
908 z = m_subsys_box[item] -> AddString(Docking_bay_list[i]);
909 m_subsys_box[item] -> SetItemDataPtr(z, Docking_bay_list[i]);
913 if (!m_behavior[item])
914 set_item(item, init);
917 m_subsys_box[item] -> EnableWindow(FALSE);
918 m_dock2_box[item] -> EnableWindow(FALSE);
924 void ShipGoalsDlg::OnSelchangeBehavior1()
928 m_subsys[0] = m_dock2[0] = 0;
933 void ShipGoalsDlg::OnSelchangeBehavior2()
938 m_subsys[1] = m_dock2[1] = 0;
942 void ShipGoalsDlg::OnSelchangeBehavior3()
947 m_subsys[2] = m_dock2[2] = 0;
951 void ShipGoalsDlg::OnSelchangeBehavior4()
956 m_subsys[3] = m_dock2[3] = 0;
960 void ShipGoalsDlg::OnSelchangeBehavior5()
965 m_subsys[4] = m_dock2[4] = 0;
969 void ShipGoalsDlg::OnSelchangeBehavior6()
974 m_subsys[5] = m_dock2[5] = 0;
978 void ShipGoalsDlg::OnSelchangeBehavior7()
983 m_subsys[6] = m_dock2[6] = 0;
987 void ShipGoalsDlg::OnSelchangeBehavior8()
992 m_subsys[7] = m_dock2[7] = 0;
996 void ShipGoalsDlg::OnSelchangeBehavior9()
1001 m_subsys[8] = m_dock2[8] = 0;
1005 void ShipGoalsDlg::OnSelchangeBehavior10()
1010 m_subsys[9] = m_dock2[9] = 0;
1014 void ShipGoalsDlg::update()
1019 for (i=0; i<ED_MAX_GOALS; i++)
1027 ptr = GET_FIRST(&obj_used_list);
1028 while (ptr != END_OF_LIST(&obj_used_list)) {
1029 if ((ptr->type == OBJ_SHIP) && (ptr->flags & OF_MARKED)) {
1030 goalp = Ai_info[Ships[ptr->instance].ai_index].goals;
1031 for (i=0; i<ED_MAX_GOALS; i++)
1035 ptr = GET_NEXT(ptr);
1038 ptr = GET_FIRST(&obj_used_list);
1039 while (ptr != END_OF_LIST(&obj_used_list)) {
1040 if ((ptr->type == OBJ_SHIP) && (ptr->flags & OF_MARKED)) {
1041 self_ship = ptr->instance;
1042 goalp = Ai_info[Ships[self_ship].ai_index].goals;
1043 verify_orders(self_ship);
1046 ptr = GET_NEXT(ptr);
1051 int ShipGoalsDlg::verify_orders(int ship)
1053 char *str, buf[2048];
1055 if ((str = error_check_initial_orders(goalp, self_ship, self_wing))!=NULL) {
1058 else if (*str == '*')
1062 sprintf(buf, "Initial orders error for ship \"%s\"\n\n%s", Ships[ship].ship_name, str);
1066 if (MessageBox(buf, "Error", MB_OKCANCEL | MB_ICONEXCLAMATION) != IDOK)
1073 void ShipGoalsDlg::update_item(int item, int multi)
1075 char *docker, *dockee, *subsys;
1077 char buf[512], save[80];
1079 if (item >= MAX_AI_GOALS)
1082 if (!multi || m_priority[item] >= 0)
1083 goalp[item].priority = m_priority[item];
1085 if (m_behavior[item] < 0) {
1089 m_behavior[item] = 0;
1092 mode = m_behavior_box[item] -> GetItemData(m_behavior[item]);
1095 case AI_GOAL_CHASE_ANY:
1096 case AI_GOAL_UNDOCK:
1097 case AI_GOAL_KEEP_SAFE_DISTANCE:
1098 case AI_GOAL_PLAY_DEAD:
1100 MODIFY(goalp[item].ai_mode, mode);
1103 case AI_GOAL_WAYPOINTS:
1104 case AI_GOAL_WAYPOINTS_ONCE:
1105 case AI_GOAL_DISABLE_SHIP:
1106 case AI_GOAL_DISARM_SHIP:
1107 case AI_GOAL_IGNORE:
1108 case AI_GOAL_EVADE_SHIP:
1109 case AI_GOAL_STAY_NEAR_SHIP:
1110 case AI_GOAL_STAY_STILL:
1113 case AI_GOAL_DESTROY_SUBSYSTEM:
1115 if (!multi || (m_data[item] && (m_subsys[item] >= 0)))
1116 subsys = (char *) m_subsys_box[item]->GetItemDataPtr(m_subsys[item]);
1117 //MODIFY(goalp[item].ai_submode, m_subsys[item] + 1);
1120 sprintf(buf, "Order #%d doesn't have valid subsystem name. Order will be removed", item + 1);
1121 MessageBox(buf, "Notice");
1122 MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
1126 if (!goalp[item].docker.name || (goalp[item].docker.name && !stricmp(goalp[item].docker.name, subsys)))
1129 goalp[item].docker.name = subsys;
1134 case AI_GOAL_CHASE | AI_GOAL_CHASE_WING:
1135 switch (m_data[item] & TYPE_MASK) {
1138 mode = AI_GOAL_CHASE;
1142 mode = AI_GOAL_CHASE_WING;
1150 if (!multi || (m_data[item] && (m_subsys[item] >= 0)))
1151 docker = (char *) m_subsys_box[item] -> GetItemDataPtr(m_subsys[item]);
1154 if (!multi || (m_data[item] && (m_dock2[item] >= 0)))
1155 dockee = (char *) m_dock2_box[item] -> GetItemDataPtr(m_dock2[item]);
1157 if (docker == (char *) 0xffffffff)
1159 if (dockee == (char *) 0xffffffff)
1162 if (!docker || !dockee) {
1163 sprintf(buf, "Order #%d doesn't have valid docking points. Order will be removed", item + 1);
1164 MessageBox(buf, "Notice");
1165 MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
1169 if (!goalp[item].docker.name)
1171 else if (!stricmp(goalp[item].docker.name, docker))
1174 if (!goalp[item].dockee.name)
1176 else if (!stricmp(goalp[item].dockee.name, dockee))
1179 goalp[item].docker.name = docker;
1180 goalp[item].dockee.name = dockee;
1185 case AI_GOAL_GUARD | AI_GOAL_GUARD_WING:
1186 switch (m_data[item] & TYPE_MASK) {
1189 mode = AI_GOAL_GUARD;
1193 mode = AI_GOAL_GUARD_WING;
1200 Warning(LOCATION, "Unknown AI_GOAL type 0x%x", mode);
1201 MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
1205 MODIFY(goalp[item].ai_mode, mode);
1208 if (goalp[item].ship_name)
1209 strcpy(save, goalp[item].ship_name);
1211 switch (m_data[item] & TYPE_MASK) {
1216 goalp[item].ship_name = ai_get_goal_ship_name(Ships[m_data[item] & DATA_MASK].ship_name, ¬_used);
1220 goalp[item].ship_name = ai_get_goal_ship_name(Wings[m_data[item] & DATA_MASK].name, ¬_used);
1224 goalp[item].ship_name = ai_get_goal_ship_name(Waypoint_lists[m_data[item] & DATA_MASK].name, ¬_used);
1228 goalp[item].ship_name = ai_get_goal_ship_name(object_name(m_data[item] & DATA_MASK), ¬_used);
1233 case (-1 & TYPE_MASK):
1237 sprintf(buf, "Order #%d doesn't have a valid target. Order will be removed", item + 1);
1238 MessageBox(buf, "Notice");
1239 MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
1246 if (stricmp(save, goalp[item].ship_name))
1250 void ShipGoalsDlg::OnOK()
1256 for (i=0; i<ED_MAX_GOALS; i++) {
1257 mode = m_behavior_box[i] -> GetItemData(m_behavior[i]);
1258 if ((mode != AI_GOAL_NONE) && (mode != AI_GOAL_CHASE_ANY) && (mode != AI_GOAL_UNDOCK) && (mode != AI_GOAL_KEEP_SAFE_DISTANCE) && (mode != AI_GOAL_PLAY_DEAD) && (mode != AI_GOAL_WARP) ) {
1259 if (!m_object_box[i] -> GetCount()) // no valid objects?
1262 m_data[i] = m_object_box[i] -> GetItemData(m_object[i]);
1270 void ShipGoalsDlg::OnSelchangeObject1()
1274 m_subsys[0] = m_dock2[0] = 0;
1278 void ShipGoalsDlg::OnSelchangeObject2()
1282 m_subsys[1] = m_dock2[1] = 0;
1286 void ShipGoalsDlg::OnSelchangeObject3()
1290 m_subsys[2] = m_dock2[2] = 0;
1294 void ShipGoalsDlg::OnSelchangeObject4()
1298 m_subsys[3] = m_dock2[3] = 0;
1302 void ShipGoalsDlg::OnSelchangeObject5()
1306 m_subsys[4] = m_dock2[4] = 0;
1310 void ShipGoalsDlg::OnSelchangeObject6()
1314 m_subsys[5] = m_dock2[5] = 0;
1318 void ShipGoalsDlg::OnSelchangeObject7()
1322 m_subsys[6] = m_dock2[6] = 0;
1326 void ShipGoalsDlg::OnSelchangeObject8()
1330 m_subsys[7] = m_dock2[7] = 0;
1334 void ShipGoalsDlg::OnSelchangeObject9()
1338 m_subsys[8] = m_dock2[8] = 0;
1342 void ShipGoalsDlg::OnSelchangeObject10()
1346 m_subsys[9] = m_dock2[9] = 0;
1350 void ShipGoalsDlg::set_object(int item)
1353 int i = 0, z, num, not_used, mode;
1354 ship_subsys *subsys;
1356 if (m_behavior[item] > 0) {
1357 mode = m_behavior_box[item] -> GetItemData(m_behavior[item]);
1358 if (!m_object_box[item] -> GetCount())
1359 m_behavior[item] = m_data[item] = 0;
1361 m_data[item] = m_object_box[item] -> GetItemData(m_object[item]);
1363 if ((mode == AI_GOAL_DOCK) && (m_data[item] >= 0)) {
1364 num = get_docking_list(Ships[m_data[item] & DATA_MASK].modelnum);
1365 m_dock2_box[item] -> EnableWindow(TRUE);
1366 m_dock2_box[item] -> ResetContent();
1367 for (i=0; i<num; i++) {
1368 SDL_assert(Docking_bay_list[i]);
1369 z = m_dock2_box[item] -> AddString(Docking_bay_list[i]);
1370 str = ai_get_goal_ship_name(Docking_bay_list[i], ¬_used);
1371 m_dock2_box[item] -> SetItemDataPtr(z, str);
1374 } else if ((mode == AI_GOAL_DESTROY_SUBSYSTEM) && (m_data[item] >= 0)) {
1375 if (((m_data[item] & TYPE_MASK) == TYPE_SHIP) || ((m_data[item] & TYPE_MASK) == TYPE_PLAYER)) {
1376 i = m_data[item] & DATA_MASK;
1381 m_subsys_box[item] -> ResetContent();
1382 subsys = GET_FIRST(&Ships[i].subsys_list);
1384 while (subsys != END_OF_LIST(&Ships[i].subsys_list)) {
1385 m_subsys_box[item]->AddString(subsys->system_info->subobj_name);
1386 m_subsys_box[item]->SetItemDataPtr(z, subsys->system_info->subobj_name);
1388 subsys = GET_NEXT(subsys);