2 * $Logfile: /Freespace2/code/fred2/ShipGoalsDlg.cpp $
7 * Initial orders editor dialog box handling code. This dialog is used for both
8 * ship and wing initial orders, and can support more if need be without modification.
11 * Revision 1.2 2002/05/07 03:16:44 theoddone33
12 * The Great Newline Fix
14 * Revision 1.1.1.1 2002/05/03 03:28:08 root
18 * 4 3/26/99 4:49p Dave
19 * Made cruisers able to dock with stuff. Made docking points and paths
22 * 3 3/25/99 3:32p Johnson
23 * HACK: Allow Mycerinus to dock
25 * 2 10/07/98 6:28p Dave
26 * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
27 * Fred. Globalized mission and campaign file extensions. Removed Silent
28 * Threat specific code.
30 * 1 10/07/98 3:01p Dave
32 * 1 10/07/98 3:00p Dave
34 * 57 7/06/98 5:12p Hoffoss
35 * Fixed bug where 3-5th orders don't update data listing when object
38 * 56 5/21/98 12:58a Hoffoss
39 * Fixed warnings optimized build turned up.
41 * 55 4/06/98 11:34a Hoffoss
42 * Fixed bug caused by change in max ai goals. Should be able to handle
43 * anything from 0 to 10 ai goals now (i.e. it's more flexible now).
45 * 54 11/05/97 4:43p Allender
46 * reworked medal/rank system to read all data from tables. Made Fred
47 * read medals.tbl. Changed ai-warp to ai-warp-out which doesn't require
48 * waypoint for activation
50 * 53 10/22/97 3:15p Hoffoss
51 * Fixed ai-stay-still initial order to use waypoints instead of waypoint
54 * 52 10/22/97 1:58p Hoffoss
55 * Added support for AI_GOALS_PLAY_DEAD and changed AI_GOALS_STAY_STILL
58 * 51 10/10/97 5:03p Allender
59 * started work on ai-stay-still
61 * 50 9/18/97 11:28a Duncan
62 * Fixed bug with player objects having wrong name.
64 * 49 9/16/97 9:41p Hoffoss
65 * Changed Fred code around to stop using Parse_player structure for
66 * player information, and use actual ships instead.
68 * 48 9/09/97 3:39p Sandeep
69 * warning level 4 bugs
71 * 47 9/02/97 5:10p Johnson
72 * Fixed bug with wing initial orders available to select from.
74 * 46 8/26/97 4:18p Hoffoss
75 * Added error checking to initial orders dialog when ok is clicked.
77 * 45 8/19/97 11:59a Duncan
78 * Fixed bug in initial orders set_item().
80 * 44 8/16/97 4:51p Hoffoss
81 * Fixed bugs with wing deletion and removing ships from a wing.
83 * 43 8/15/97 5:14p Hoffoss
84 * Completely changed around how initial orders dialog worked. It's
87 * 42 8/14/97 7:07p Hoffoss
88 * Changed "guard ship" to "guard", since it can be used with wings now as
91 * 41 8/10/97 4:41p Hoffoss
92 * Fixed bugs with docking initial order.
94 * 40 8/05/97 10:10p Hoffoss
95 * Made attack and guard orders handle both ships and wings as targets.
97 * 39 8/01/97 12:21p Jasen
98 * Fixed bug with docking order (in iinitial orders) where original dockee
99 * was deleted, and so not found when looked up.
101 * 38 7/30/97 12:31p Hoffoss
102 * Made improvements to ship goals editor (initial orders) to disallow
105 * 37 7/25/97 4:30p Hoffoss
106 * Changes to ship lookup to include player ships.
108 * 36 7/24/97 4:55p Allender
109 * added ai-evade-ship to fred and to Freespace
111 * 35 7/22/97 3:40p Allender
112 * Changed the way that attacking subsystem works (for initial orders).
113 * The code was behaving two different ways. Orders are now model
114 * specific as per which subsystem to attack.
116 * 34 7/17/97 4:23p Allender
117 * ai-guard-wing now in both Fred and Freespace
119 * 33 7/09/97 1:56p Jasen
120 * Added new case to data mode checkunder save item.
122 * 32 6/11/97 2:13p Hoffoss
123 * Fixed bug in initial order initialization, and made subsystem combo box
124 * use ship specific subsystems.
126 * 31 6/04/97 12:00a Allender
127 * added disarm and disable as initial order options
129 * 30 5/30/97 4:50p Hoffoss
130 * Added code to allow marked ship editing of data in child dialogs of
131 * ship editor dialog.
133 * 29 5/07/97 1:32p Allender
134 * fix bug from previous checkin where undock orders were not persistent
136 * 28 5/07/97 1:08p Allender
137 * make undock initial order only accept a priority
139 * 27 4/03/97 3:18p Allender
141 * 26 3/31/97 6:07p Hoffoss
142 * Fixed several errors, including BG editor not graying fields, BG editor
143 * not updating image when changed, Removed obsolete data from Weapon
144 * editor, priority not being saved when missions saved, priority not
145 * editable in initial orders editor.
147 * 25 3/28/97 3:19p Hoffoss
148 * Added chase-any goal to initial orders.
150 * 24 3/21/97 4:04p Bernal
151 * fixed crash when initial orders references illegal objects. (Jason)
153 * 23 3/21/97 10:29a Hoffoss
154 * forced negative priorities to 50
156 * 22 3/19/97 4:53p Hoffoss
157 * fixed bug with unused fields not being cleared.
159 * 21 3/13/97 12:20p Hoffoss
160 * fixed bug in docking point specification of initial orders dialog.
162 * 20 3/10/97 6:43p Hoffoss
163 * Standardized docking goal usage by fred to use names instead of
166 * 19 3/10/97 5:37p Hoffoss
167 * fixed bug in dock goal selection.
169 * 18 3/10/97 12:54p Hoffoss
170 * Added drop down combo box to toolbar and fixed compiling errors Mark
171 * (maybe Mike?) introduced to code.
173 * 17 3/04/97 12:52p Allender
174 * docking styff. Added dock type to docking structure in model code.
175 * Renamed structure member in ai_goals. Temporary checkin. (i.e.
176 * rearming will use rearm dock points)
178 * 16 3/03/97 4:32p Hoffoss
179 * Initial orders supports new docking stuff Allender added.
181 * 15 2/27/97 3:15p Allender
182 * major wing structure enhancement. simplified wing code. All around
183 * better wing support
185 * 14 2/26/97 2:45p Hoffoss
186 * Initial orders dialog now only allows 89 as a max on priority.
188 * 13 2/21/97 5:34p Hoffoss
189 * Added extensive modification detection and fixed a bug in initial
192 * 12 2/17/97 5:28p Hoffoss
193 * Checked RCS headers, added them were missing, changing description to
194 * something better, etc where needed.
201 #include "shipgoalsdlg.h"
203 #include "linklist.h"
204 #include "management.h"
207 #include "fredview.h"
209 #define TYPE_PATH 0x1000
210 #define TYPE_SHIP 0x2000
211 #define TYPE_PLAYER 0x3000
212 #define TYPE_WING 0x4000
213 #define TYPE_WAYPOINT 0x5000
214 #define TYPE_MASK 0xf000
215 #define DATA_MASK 0x0fff
218 #define new DEBUG_NEW
220 static char THIS_FILE[] = __FILE__;
223 /////////////////////////////////////////////////////////////////////////////
224 // ShipGoalsDlg dialog
226 ShipGoalsDlg::ShipGoalsDlg(CWnd* pParent /*=NULL*/)
227 : CDialog(ShipGoalsDlg::IDD, pParent)
231 for (i=0; i<ED_MAX_GOALS; i++) {
240 //{{AFX_DATA_INIT(ShipGoalsDlg)
243 self_ship = self_wing = -1;
246 void ShipGoalsDlg::DoDataExchange(CDataExchange* pDX)
248 CDialog::DoDataExchange(pDX);
249 //{{AFX_DATA_MAP(ShipGoalsDlg)
252 DDX_CBIndex(pDX, IDC_BEHAVIOR1, m_behavior[0]);
253 DDX_CBIndex(pDX, IDC_BEHAVIOR2, m_behavior[1]);
254 DDX_CBIndex(pDX, IDC_BEHAVIOR3, m_behavior[2]);
255 DDX_CBIndex(pDX, IDC_BEHAVIOR4, m_behavior[3]);
256 DDX_CBIndex(pDX, IDC_BEHAVIOR5, m_behavior[4]);
257 DDX_CBIndex(pDX, IDC_BEHAVIOR6, m_behavior[5]);
258 DDX_CBIndex(pDX, IDC_BEHAVIOR7, m_behavior[6]);
259 DDX_CBIndex(pDX, IDC_BEHAVIOR8, m_behavior[7]);
260 DDX_CBIndex(pDX, IDC_BEHAVIOR9, m_behavior[8]);
261 DDX_CBIndex(pDX, IDC_BEHAVIOR10, m_behavior[9]);
263 DDX_CBIndex(pDX, IDC_OBJECT1, m_object[0]);
264 DDX_CBIndex(pDX, IDC_OBJECT2, m_object[1]);
265 DDX_CBIndex(pDX, IDC_OBJECT3, m_object[2]);
266 DDX_CBIndex(pDX, IDC_OBJECT4, m_object[3]);
267 DDX_CBIndex(pDX, IDC_OBJECT5, m_object[4]);
268 DDX_CBIndex(pDX, IDC_OBJECT6, m_object[5]);
269 DDX_CBIndex(pDX, IDC_OBJECT7, m_object[6]);
270 DDX_CBIndex(pDX, IDC_OBJECT8, m_object[7]);
271 DDX_CBIndex(pDX, IDC_OBJECT9, m_object[8]);
272 DDX_CBIndex(pDX, IDC_OBJECT10, m_object[9]);
274 DDX_Text(pDX, IDC_PRIORITY1, m_priority[0]);
275 DDV_MinMaxInt(pDX, m_priority[0], 0, 89);
276 DDX_Text(pDX, IDC_PRIORITY2, m_priority[1]);
277 DDV_MinMaxInt(pDX, m_priority[1], 0, 89);
278 DDX_Text(pDX, IDC_PRIORITY3, m_priority[2]);
279 DDV_MinMaxInt(pDX, m_priority[2], 0, 89);
280 DDX_Text(pDX, IDC_PRIORITY4, m_priority[3]);
281 DDV_MinMaxInt(pDX, m_priority[3], 0, 89);
282 DDX_Text(pDX, IDC_PRIORITY5, m_priority[4]);
283 DDV_MinMaxInt(pDX, m_priority[4], 0, 89);
284 DDX_Text(pDX, IDC_PRIORITY6, m_priority[5]);
285 DDV_MinMaxInt(pDX, m_priority[5], 0, 89);
286 DDX_Text(pDX, IDC_PRIORITY7, m_priority[6]);
287 DDV_MinMaxInt(pDX, m_priority[6], 0, 89);
288 DDX_Text(pDX, IDC_PRIORITY8, m_priority[7]);
289 DDV_MinMaxInt(pDX, m_priority[7], 0, 89);
290 DDX_Text(pDX, IDC_PRIORITY9, m_priority[8]);
291 DDV_MinMaxInt(pDX, m_priority[8], 0, 89);
292 DDX_Text(pDX, IDC_PRIORITY10, m_priority[9]);
293 DDV_MinMaxInt(pDX, m_priority[9], 0, 89);
295 DDX_CBIndex(pDX, IDC_SUBSYSTEM1, m_subsys[0]);
296 DDX_CBIndex(pDX, IDC_SUBSYSTEM2, m_subsys[1]);
297 DDX_CBIndex(pDX, IDC_SUBSYSTEM3, m_subsys[2]);
298 DDX_CBIndex(pDX, IDC_SUBSYSTEM4, m_subsys[3]);
299 DDX_CBIndex(pDX, IDC_SUBSYSTEM5, m_subsys[4]);
300 DDX_CBIndex(pDX, IDC_SUBSYSTEM6, m_subsys[5]);
301 DDX_CBIndex(pDX, IDC_SUBSYSTEM7, m_subsys[6]);
302 DDX_CBIndex(pDX, IDC_SUBSYSTEM8, m_subsys[7]);
303 DDX_CBIndex(pDX, IDC_SUBSYSTEM9, m_subsys[8]);
304 DDX_CBIndex(pDX, IDC_SUBSYSTEM10, m_subsys[9]);
306 DDX_CBIndex(pDX, IDC_DOCK1, m_dock2[0]);
307 DDX_CBIndex(pDX, IDC_DOCK2, m_dock2[1]);
308 DDX_CBIndex(pDX, IDC_DOCK3, m_dock2[2]);
309 DDX_CBIndex(pDX, IDC_DOCK4, m_dock2[3]);
310 DDX_CBIndex(pDX, IDC_DOCK5, m_dock2[4]);
311 DDX_CBIndex(pDX, IDC_DOCK6, m_dock2[5]);
312 DDX_CBIndex(pDX, IDC_DOCK7, m_dock2[6]);
313 DDX_CBIndex(pDX, IDC_DOCK8, m_dock2[7]);
314 DDX_CBIndex(pDX, IDC_DOCK9, m_dock2[8]);
315 DDX_CBIndex(pDX, IDC_DOCK10, m_dock2[9]);
318 BEGIN_MESSAGE_MAP(ShipGoalsDlg, CDialog)
319 //{{AFX_MSG_MAP(ShipGoalsDlg)
320 ON_CBN_SELCHANGE(IDC_BEHAVIOR1, OnSelchangeBehavior1)
321 ON_CBN_SELCHANGE(IDC_BEHAVIOR2, OnSelchangeBehavior2)
322 ON_CBN_SELCHANGE(IDC_BEHAVIOR3, OnSelchangeBehavior3)
323 ON_CBN_SELCHANGE(IDC_BEHAVIOR4, OnSelchangeBehavior4)
324 ON_CBN_SELCHANGE(IDC_BEHAVIOR5, OnSelchangeBehavior5)
325 ON_CBN_SELCHANGE(IDC_BEHAVIOR6, OnSelchangeBehavior6)
326 ON_CBN_SELCHANGE(IDC_BEHAVIOR7, OnSelchangeBehavior7)
327 ON_CBN_SELCHANGE(IDC_BEHAVIOR8, OnSelchangeBehavior8)
328 ON_CBN_SELCHANGE(IDC_BEHAVIOR9, OnSelchangeBehavior9)
329 ON_CBN_SELCHANGE(IDC_BEHAVIOR10, OnSelchangeBehavior10)
330 ON_CBN_SELCHANGE(IDC_OBJECT1, OnSelchangeObject1)
331 ON_CBN_SELCHANGE(IDC_OBJECT2, OnSelchangeObject2)
332 ON_CBN_SELCHANGE(IDC_OBJECT3, OnSelchangeObject3)
333 ON_CBN_SELCHANGE(IDC_OBJECT4, OnSelchangeObject4)
334 ON_CBN_SELCHANGE(IDC_OBJECT5, OnSelchangeObject5)
335 ON_CBN_SELCHANGE(IDC_OBJECT6, OnSelchangeObject6)
336 ON_CBN_SELCHANGE(IDC_OBJECT7, OnSelchangeObject7)
337 ON_CBN_SELCHANGE(IDC_OBJECT8, OnSelchangeObject8)
338 ON_CBN_SELCHANGE(IDC_OBJECT9, OnSelchangeObject9)
339 ON_CBN_SELCHANGE(IDC_OBJECT10, OnSelchangeObject10)
343 /////////////////////////////////////////////////////////////////////////////
344 // ShipGoalsDlg message handlers
346 BOOL ShipGoalsDlg::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
348 return CDialog::Create(IDD, &Ship_editor_dialog);
351 BOOL ShipGoalsDlg::OnInitDialog()
353 int i, j, z, valid[99];
356 // set up pointers to all the combo boxes to simplify things a lot
357 m_behavior_box[0] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR1);
358 m_behavior_box[1] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR2);
359 m_behavior_box[2] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR3);
360 m_behavior_box[3] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR4);
361 m_behavior_box[4] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR5);
362 m_behavior_box[5] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR6);
363 m_behavior_box[6] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR7);
364 m_behavior_box[7] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR8);
365 m_behavior_box[8] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR9);
366 m_behavior_box[9] = (CComboBox *) GetDlgItem(IDC_BEHAVIOR10);
368 m_object_box[0] = (CComboBox *) GetDlgItem(IDC_OBJECT1);
369 m_object_box[1] = (CComboBox *) GetDlgItem(IDC_OBJECT2);
370 m_object_box[2] = (CComboBox *) GetDlgItem(IDC_OBJECT3);
371 m_object_box[3] = (CComboBox *) GetDlgItem(IDC_OBJECT4);
372 m_object_box[4] = (CComboBox *) GetDlgItem(IDC_OBJECT5);
373 m_object_box[5] = (CComboBox *) GetDlgItem(IDC_OBJECT6);
374 m_object_box[6] = (CComboBox *) GetDlgItem(IDC_OBJECT7);
375 m_object_box[7] = (CComboBox *) GetDlgItem(IDC_OBJECT8);
376 m_object_box[8] = (CComboBox *) GetDlgItem(IDC_OBJECT9);
377 m_object_box[9] = (CComboBox *) GetDlgItem(IDC_OBJECT10);
379 m_subsys_box[0] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM1);
380 m_subsys_box[1] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM2);
381 m_subsys_box[2] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM3);
382 m_subsys_box[3] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM4);
383 m_subsys_box[4] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM5);
384 m_subsys_box[5] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM6);
385 m_subsys_box[6] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM7);
386 m_subsys_box[7] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM8);
387 m_subsys_box[8] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM9);
388 m_subsys_box[9] = (CComboBox *) GetDlgItem(IDC_SUBSYSTEM10);
390 m_dock2_box[0] = (CComboBox *) GetDlgItem(IDC_DOCK1);
391 m_dock2_box[1] = (CComboBox *) GetDlgItem(IDC_DOCK2);
392 m_dock2_box[2] = (CComboBox *) GetDlgItem(IDC_DOCK3);
393 m_dock2_box[3] = (CComboBox *) GetDlgItem(IDC_DOCK4);
394 m_dock2_box[4] = (CComboBox *) GetDlgItem(IDC_DOCK5);
395 m_dock2_box[5] = (CComboBox *) GetDlgItem(IDC_DOCK6);
396 m_dock2_box[6] = (CComboBox *) GetDlgItem(IDC_DOCK7);
397 m_dock2_box[7] = (CComboBox *) GetDlgItem(IDC_DOCK8);
398 m_dock2_box[8] = (CComboBox *) GetDlgItem(IDC_DOCK9);
399 m_dock2_box[9] = (CComboBox *) GetDlgItem(IDC_DOCK10);
401 m_priority_box[0] = (CComboBox *) GetDlgItem(IDC_PRIORITY1);
402 m_priority_box[1] = (CComboBox *) GetDlgItem(IDC_PRIORITY2);
403 m_priority_box[2] = (CComboBox *) GetDlgItem(IDC_PRIORITY3);
404 m_priority_box[3] = (CComboBox *) GetDlgItem(IDC_PRIORITY4);
405 m_priority_box[4] = (CComboBox *) GetDlgItem(IDC_PRIORITY5);
406 m_priority_box[5] = (CComboBox *) GetDlgItem(IDC_PRIORITY6);
407 m_priority_box[6] = (CComboBox *) GetDlgItem(IDC_PRIORITY7);
408 m_priority_box[7] = (CComboBox *) GetDlgItem(IDC_PRIORITY8);
409 m_priority_box[8] = (CComboBox *) GetDlgItem(IDC_PRIORITY9);
410 m_priority_box[9] = (CComboBox *) GetDlgItem(IDC_PRIORITY10);
412 // start off with all goals available
413 for (i=0; i<Ai_goal_list_size; i++)
416 // disallow orders if they aren't allowed because of ship type
417 if (self_ship >= 0) { // editing orders for just one ship
418 for (i=0; i<Ai_goal_list_size; i++){
419 if (!(ai_query_goal_valid(self_ship, Ai_goal_list[i].def))){
423 } else if (self_wing >= 0) { // editing orders for just one wing
424 for (i=0; i<Wings[self_wing].wave_count; i++){
425 for (j=0; j<Ai_goal_list_size; j++){
426 if (!ai_query_goal_valid(Wings[self_wing].ship_index[i], Ai_goal_list[j].def)){
432 for (i=0; i<Ai_goal_list_size; i++){
433 if (Ai_goal_list[i].def == AI_GOAL_DOCK){ // a whole wing can't dock with one object..
437 } else { // editing orders for all marked ships
438 ptr = GET_FIRST(&obj_used_list);
439 while (ptr != END_OF_LIST(&obj_used_list)) {
440 if ((ptr->type == OBJ_SHIP) && (ptr->flags & OF_MARKED)){
441 for (i=0; i<Ai_goal_list_size; i++){
442 if (!ai_query_goal_valid(ptr->instance, Ai_goal_list[i].def)){
452 for (i=0; i<MAX_WAYPOINT_LISTS; i++){
453 if (Waypoint_lists[i].count){
458 if (i == MAX_WAYPOINT_LISTS){
459 for (i=0; i<Ai_goal_list_size; i++){
460 switch (Ai_goal_list[i].def) {
461 case AI_GOAL_WAYPOINTS:
462 case AI_GOAL_WAYPOINTS_ONCE:
470 ptr = GET_FIRST(&obj_used_list);
471 while (ptr != END_OF_LIST(&obj_used_list)) {
472 if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) {
475 if ((self_ship > 0) && (self_ship != i) && ship_docking_valid(self_ship, i)){
483 for (i=0; i<Ai_goal_list_size; i++){
484 if (Ai_goal_list[i].def == AI_GOAL_DOCK){
490 // initialize the behavior boxes (they remain constant) and initialize each goal's data
491 for (i=0; i<ED_MAX_GOALS; i++) {
492 m_behavior_box[i] -> ResetContent();
493 z = m_behavior_box[i] -> AddString("None");
494 m_behavior_box[i] -> SetItemData(z, (DWORD) AI_GOAL_NONE);
495 for (j=0; j<Ai_goal_list_size; j++){
497 z = m_behavior_box[i] -> AddString(Ai_goal_list[j].name);
498 m_behavior_box[i] -> SetItemData(z, (DWORD) Ai_goal_list[j].def);
504 initialize(Ai_info[Ships[self_ship].ai_index].goals, self_ship);
505 } else if (self_wing >= 0){
506 initialize(Wings[self_wing].ai_goals);
511 for (i=0; i<ED_MAX_GOALS; i++){
515 CDialog::OnInitDialog();
517 // restrict spin controls to a range of 0 - 89
518 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN1)) -> SetRange(0, 89);
519 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN2)) -> SetRange(0, 89);
520 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN3)) -> SetRange(0, 89);
521 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN4)) -> SetRange(0, 89);
522 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN5)) -> SetRange(0, 89);
523 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN6)) -> SetRange(0, 89);
524 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN7)) -> SetRange(0, 89);
525 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN8)) -> SetRange(0, 89);
526 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN9)) -> SetRange(0, 89);
527 ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN10)) -> SetRange(0, 89);
532 void ShipGoalsDlg::initialize_multi()
536 int behavior[ED_MAX_GOALS];
537 int priority[ED_MAX_GOALS];
538 int subsys[ED_MAX_GOALS];
539 int dock2[ED_MAX_GOALS];
540 int data[ED_MAX_GOALS];
542 ptr = GET_FIRST(&obj_used_list);
543 while (ptr != END_OF_LIST(&obj_used_list)) {
544 if ((ptr->type == OBJ_SHIP) && (ptr->flags & OF_MARKED)) {
545 initialize(Ai_info[Ships[ptr->instance].ai_index].goals, ptr->instance);
548 for (i=0; i<ED_MAX_GOALS; i++) {
549 behavior[i] = m_behavior[i];
550 priority[i] = m_priority[i];
551 subsys[i] = m_subsys[i];
552 dock2[i] = m_dock2[i];
557 for (i=0; i<ED_MAX_GOALS; i++) {
558 if (behavior[i] != m_behavior[i]) {
563 if (data[i] != m_data[i]) {
569 if (priority[i] != m_priority[i]){
572 if (subsys[i] != m_subsys[i]){
575 if (dock2[i] != m_dock2[i]){
586 for (i=0; i<ED_MAX_GOALS; i++) {
587 m_behavior[i] = behavior[i];
588 m_priority[i] = priority[i];
589 m_subsys[i] = subsys[i];
590 m_dock2[i] = dock2[i];
595 // perform one-time initialization of data from the goals struct.
596 void ShipGoalsDlg::initialize(ai_goal *goals, int ship)
598 int i, item, num, inst, flag, mode;
602 for (item=0; item<ED_MAX_GOALS; item++) {
605 m_priority[item] = 0;
608 if (item < MAX_AI_GOALS) {
609 m_priority[item] = goalp[item].priority;
610 mode = goalp[item].ai_mode;
613 if (m_priority[item] < 0 || m_priority[item] > 89){
614 m_priority[item] = 50;
617 m_behavior[item] = 0;
618 if (mode != AI_GOAL_NONE) {
619 i = m_behavior_box[item] -> GetCount();
621 if (mode & (m_behavior_box[item]->GetItemData(i))) {
622 m_behavior[item] = i;
630 case AI_GOAL_CHASE_ANY:
632 case AI_GOAL_KEEP_SAFE_DISTANCE:
633 case AI_GOAL_PLAY_DEAD:
637 case AI_GOAL_STAY_STILL:
638 flag = 9; // target is a ship or a waypoint
643 case AI_GOAL_DISABLE_SHIP:
644 case AI_GOAL_DISARM_SHIP:
646 case AI_GOAL_EVADE_SHIP:
647 case AI_GOAL_STAY_NEAR_SHIP:
650 case AI_GOAL_WAYPOINTS:
651 case AI_GOAL_WAYPOINTS_ONCE:
652 flag = 4; // target is a waypoint
655 case AI_GOAL_DESTROY_SUBSYSTEM:
656 num = ship_name_lookup(goalp[item].ship_name, 1);
658 m_subsys[item] = ship_get_subsys_index(&Ships[num], goalp[item].docker.name, 1);
664 num = get_docking_list(Ships[ship].modelnum);
665 for (i=0; i<num; i++) {
666 Assert(Docking_bay_list[i]);
667 if (!stricmp(goalp[item].docker.name, Docking_bay_list[i])) {
675 case AI_GOAL_CHASE_WING:
676 case AI_GOAL_GUARD_WING:
677 flag = 2; // target is a wing
685 ptr = GET_FIRST(&obj_used_list);
686 while (ptr != END_OF_LIST(&obj_used_list)) {
687 if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) {
688 inst = ptr->instance;
689 if (ptr->type == OBJ_SHIP) {
690 Assert(inst >= 0 && inst < MAX_SHIPS);
691 if (!stricmp(goalp[item].ship_name, Ships[inst].ship_name)) {
692 m_data[item] = inst | TYPE_SHIP;
697 Assert(inst >= 0 && inst < MAX_SHIPS);
698 if (!stricmp(goalp[item].ship_name, Ships[inst].ship_name)) {
699 m_data[item] = inst | TYPE_PLAYER;
710 for (i=0; i<MAX_WINGS; i++)
711 if (Wings[i].wave_count) {
712 if (!stricmp(goalp[item].ship_name, Wings[i].name)) {
713 m_data[item] = i | TYPE_WING;
719 if (flag & 0x4) { // data is a waypoint path name
720 for (i=0; i<Num_waypoint_lists; i++)
721 if (!stricmp(goalp[item].ship_name, Waypoint_lists[i].name)) {
722 m_data[item] = i | TYPE_PATH;
727 if (flag & 0x8) { // data is a waypoint name
728 i = waypoint_lookup(goalp[item].ship_name);
730 m_data[item] = i | TYPE_WAYPOINT;
737 num = get_docking_list(Ships[m_data[item] & DATA_MASK].modelnum);
738 for (i=0; i<num; i++) {
739 Assert(Docking_bay_list[i]);
740 Assert(goalp[item].dockee.name);
741 Assert(goalp[item].dockee.index != -1);
742 if (!stricmp(goalp[item].dockee.name, Docking_bay_list[i])) {
752 // Assert(m_data[item]);
756 void ShipGoalsDlg::set_item(int item, int init)
758 int i, t, z, num, inst, mode;
764 if (item >= MAX_AI_GOALS)
765 m_behavior_box[item] -> EnableWindow(FALSE);
767 Assert(item >= 0 && item < ED_MAX_GOALS);
768 m_object_box[item] -> ResetContent();
769 if (m_behavior[item] < 1) {
770 m_object_box[item] -> EnableWindow(FALSE);
771 m_subsys_box[item] -> EnableWindow(FALSE);
772 m_dock2_box[item] -> EnableWindow(FALSE);
773 m_priority_box[item] -> EnableWindow(FALSE);
779 mode = m_behavior_box[item] -> GetItemData(m_behavior[item]);
780 m_priority_box[item] -> EnableWindow(TRUE);
781 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) ) {
782 m_object_box[item] -> EnableWindow(FALSE);
783 m_subsys_box[item] -> EnableWindow(FALSE);
784 m_dock2_box[item] -> EnableWindow(FALSE);
790 m_object_box[item] -> EnableWindow(TRUE);
793 case AI_GOAL_WAYPOINTS:
794 case AI_GOAL_WAYPOINTS_ONCE:
796 for (i=0; i<MAX_WAYPOINT_LISTS; i++)
797 if (Waypoint_lists[i].count) {
798 z = m_object_box[item] -> AddString(Waypoint_lists[i].name);
799 m_object_box[item] -> SetItemData(z, i | TYPE_PATH);
800 if (init && (m_data[item] == (i | TYPE_PATH)))
806 case AI_GOAL_STAY_STILL:
807 ptr = GET_FIRST(&obj_used_list);
808 while (ptr != END_OF_LIST(&obj_used_list)) {
809 if (ptr->type == OBJ_WAYPOINT) {
811 z = m_object_box[item] -> AddString(object_name(OBJ_INDEX(ptr)));
812 m_object_box[item] -> SetItemData(z, OBJ_INDEX(ptr) | TYPE_WAYPOINT);
813 if (init && (m_data[item] == (OBJ_INDEX(ptr) | TYPE_WAYPOINT)))
824 case AI_GOAL_DESTROY_SUBSYSTEM:
825 case AI_GOAL_CHASE | AI_GOAL_CHASE_WING:
827 case AI_GOAL_GUARD | AI_GOAL_GUARD_WING:
828 case AI_GOAL_DISABLE_SHIP:
829 case AI_GOAL_DISARM_SHIP:
830 case AI_GOAL_EVADE_SHIP:
832 case AI_GOAL_STAY_NEAR_SHIP:
833 case AI_GOAL_STAY_STILL:
834 ptr = GET_FIRST(&obj_used_list);
835 while (ptr != END_OF_LIST(&obj_used_list)) {
836 if (ptr->type == OBJ_SHIP || ptr->type == OBJ_START) {
837 inst = ptr->instance;
838 if (ptr->type == OBJ_SHIP)
843 Assert(inst >= 0 && inst < MAX_SHIPS);
844 // remove all marked ships from list
845 if (!goalp && (ptr->flags & OF_MARKED))
848 // when docking, remove invalid dock targets
849 else if (mode == AI_GOAL_DOCK) {
850 if (self_ship < 0 || !ship_docking_valid(self_ship, inst))
854 // disallow ship being it's own target
855 if (inst >= 0 && inst != self_ship) {
856 z = m_object_box[item] -> AddString(Ships[inst].ship_name);
857 m_object_box[item] -> SetItemData(z, inst | t);
858 if (init && (m_data[item] == (inst | t)))
870 case AI_GOAL_CHASE | AI_GOAL_CHASE_WING:
871 case AI_GOAL_GUARD | AI_GOAL_GUARD_WING:
872 for (i=0; i<MAX_WINGS; i++)
873 if (Wings[i].wave_count && i != self_wing) {
874 z = m_object_box[item] -> AddString(Wings[i].name);
875 m_object_box[item] -> SetItemData(z, i | TYPE_WING);
876 if (init && (m_data[item] == (i | TYPE_WING)))
883 if (mode == AI_GOAL_DESTROY_SUBSYSTEM) {
884 m_subsys_box[item] -> EnableWindow(TRUE);
885 m_dock2_box[item] -> EnableWindow(FALSE);
888 if (!m_behavior[item])
889 set_item(item, init);
891 } else if (mode == AI_GOAL_DOCK) {
892 num = get_docking_list(Ships[cur_ship].modelnum);
893 m_subsys_box[item] -> EnableWindow(TRUE);
894 m_subsys_box[item] -> ResetContent();
895 for (i=0; i<num; i++) {
896 Assert(Docking_bay_list[i]);
897 z = m_subsys_box[item] -> AddString(Docking_bay_list[i]);
898 m_subsys_box[item] -> SetItemDataPtr(z, Docking_bay_list[i]);
902 if (!m_behavior[item])
903 set_item(item, init);
906 m_subsys_box[item] -> EnableWindow(FALSE);
907 m_dock2_box[item] -> EnableWindow(FALSE);
913 void ShipGoalsDlg::OnSelchangeBehavior1()
917 m_subsys[0] = m_dock2[0] = 0;
922 void ShipGoalsDlg::OnSelchangeBehavior2()
927 m_subsys[1] = m_dock2[1] = 0;
931 void ShipGoalsDlg::OnSelchangeBehavior3()
936 m_subsys[2] = m_dock2[2] = 0;
940 void ShipGoalsDlg::OnSelchangeBehavior4()
945 m_subsys[3] = m_dock2[3] = 0;
949 void ShipGoalsDlg::OnSelchangeBehavior5()
954 m_subsys[4] = m_dock2[4] = 0;
958 void ShipGoalsDlg::OnSelchangeBehavior6()
963 m_subsys[5] = m_dock2[5] = 0;
967 void ShipGoalsDlg::OnSelchangeBehavior7()
972 m_subsys[6] = m_dock2[6] = 0;
976 void ShipGoalsDlg::OnSelchangeBehavior8()
981 m_subsys[7] = m_dock2[7] = 0;
985 void ShipGoalsDlg::OnSelchangeBehavior9()
990 m_subsys[8] = m_dock2[8] = 0;
994 void ShipGoalsDlg::OnSelchangeBehavior10()
999 m_subsys[9] = m_dock2[9] = 0;
1003 void ShipGoalsDlg::update()
1008 for (i=0; i<ED_MAX_GOALS; i++)
1016 ptr = GET_FIRST(&obj_used_list);
1017 while (ptr != END_OF_LIST(&obj_used_list)) {
1018 if ((ptr->type == OBJ_SHIP) && (ptr->flags & OF_MARKED)) {
1019 goalp = Ai_info[Ships[ptr->instance].ai_index].goals;
1020 for (i=0; i<ED_MAX_GOALS; i++)
1024 ptr = GET_NEXT(ptr);
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 self_ship = ptr->instance;
1031 goalp = Ai_info[Ships[self_ship].ai_index].goals;
1032 verify_orders(self_ship);
1035 ptr = GET_NEXT(ptr);
1040 int ShipGoalsDlg::verify_orders(int ship)
1042 char *str, buf[2048];
1044 if ((str = error_check_initial_orders(goalp, self_ship, self_wing))!=NULL) {
1047 else if (*str == '*')
1051 sprintf(buf, "Initial orders error for ship \"%s\"\n\n%s", Ships[ship].ship_name, str);
1055 if (MessageBox(buf, "Error", MB_OKCANCEL | MB_ICONEXCLAMATION) != IDOK)
1062 void ShipGoalsDlg::update_item(int item, int multi)
1064 char *docker, *dockee, *subsys;
1066 char buf[512], save[80];
1068 if (item >= MAX_AI_GOALS)
1071 if (!multi || m_priority[item] >= 0)
1072 goalp[item].priority = m_priority[item];
1074 if (m_behavior[item] < 0) {
1078 m_behavior[item] = 0;
1081 mode = m_behavior_box[item] -> GetItemData(m_behavior[item]);
1084 case AI_GOAL_CHASE_ANY:
1085 case AI_GOAL_UNDOCK:
1086 case AI_GOAL_KEEP_SAFE_DISTANCE:
1087 case AI_GOAL_PLAY_DEAD:
1089 MODIFY(goalp[item].ai_mode, mode);
1092 case AI_GOAL_WAYPOINTS:
1093 case AI_GOAL_WAYPOINTS_ONCE:
1094 case AI_GOAL_DISABLE_SHIP:
1095 case AI_GOAL_DISARM_SHIP:
1096 case AI_GOAL_IGNORE:
1097 case AI_GOAL_EVADE_SHIP:
1098 case AI_GOAL_STAY_NEAR_SHIP:
1099 case AI_GOAL_STAY_STILL:
1102 case AI_GOAL_DESTROY_SUBSYSTEM:
1104 if (!multi || (m_data[item] && (m_subsys[item] >= 0)))
1105 subsys = (char *) m_subsys_box[item]->GetItemDataPtr(m_subsys[item]);
1106 //MODIFY(goalp[item].ai_submode, m_subsys[item] + 1);
1109 sprintf(buf, "Order #%d doesn't have valid subsystem name. Order will be removed", item + 1);
1110 MessageBox(buf, "Notice");
1111 MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
1115 if (!goalp[item].docker.name || (goalp[item].docker.name && !stricmp(goalp[item].docker.name, subsys)))
1118 goalp[item].docker.name = subsys;
1123 case AI_GOAL_CHASE | AI_GOAL_CHASE_WING:
1124 switch (m_data[item] & TYPE_MASK) {
1127 mode = AI_GOAL_CHASE;
1131 mode = AI_GOAL_CHASE_WING;
1139 if (!multi || (m_data[item] && (m_subsys[item] >= 0)))
1140 docker = (char *) m_subsys_box[item] -> GetItemDataPtr(m_subsys[item]);
1143 if (!multi || (m_data[item] && (m_dock2[item] >= 0)))
1144 dockee = (char *) m_dock2_box[item] -> GetItemDataPtr(m_dock2[item]);
1146 if (docker == (char *) 0xffffffff)
1148 if (dockee == (char *) 0xffffffff)
1151 if (!docker || !dockee) {
1152 sprintf(buf, "Order #%d doesn't have valid docking points. Order will be removed", item + 1);
1153 MessageBox(buf, "Notice");
1154 MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
1158 if (!goalp[item].docker.name)
1160 else if (!stricmp(goalp[item].docker.name, docker))
1163 if (!goalp[item].dockee.name)
1165 else if (!stricmp(goalp[item].dockee.name, dockee))
1168 goalp[item].docker.name = docker;
1169 goalp[item].dockee.name = dockee;
1174 case AI_GOAL_GUARD | AI_GOAL_GUARD_WING:
1175 switch (m_data[item] & TYPE_MASK) {
1178 mode = AI_GOAL_GUARD;
1182 mode = AI_GOAL_GUARD_WING;
1189 Warning(LOCATION, "Unknown AI_GOAL type 0x%x", mode);
1190 MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
1194 MODIFY(goalp[item].ai_mode, mode);
1197 if (goalp[item].ship_name)
1198 strcpy(save, goalp[item].ship_name);
1200 switch (m_data[item] & TYPE_MASK) {
1205 goalp[item].ship_name = ai_get_goal_ship_name(Ships[m_data[item] & DATA_MASK].ship_name, ¬_used);
1209 goalp[item].ship_name = ai_get_goal_ship_name(Wings[m_data[item] & DATA_MASK].name, ¬_used);
1213 goalp[item].ship_name = ai_get_goal_ship_name(Waypoint_lists[m_data[item] & DATA_MASK].name, ¬_used);
1217 goalp[item].ship_name = ai_get_goal_ship_name(object_name(m_data[item] & DATA_MASK), ¬_used);
1222 case (-1 & TYPE_MASK):
1226 sprintf(buf, "Order #%d doesn't have a valid target. Order will be removed", item + 1);
1227 MessageBox(buf, "Notice");
1228 MODIFY(goalp[item].ai_mode, AI_GOAL_NONE);
1235 if (stricmp(save, goalp[item].ship_name))
1239 void ShipGoalsDlg::OnOK()
1245 for (i=0; i<ED_MAX_GOALS; i++) {
1246 mode = m_behavior_box[i] -> GetItemData(m_behavior[i]);
1247 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) ) {
1248 if (!m_object_box[i] -> GetCount()) // no valid objects?
1251 m_data[i] = m_object_box[i] -> GetItemData(m_object[i]);
1259 void ShipGoalsDlg::OnSelchangeObject1()
1263 m_subsys[0] = m_dock2[0] = 0;
1267 void ShipGoalsDlg::OnSelchangeObject2()
1271 m_subsys[1] = m_dock2[1] = 0;
1275 void ShipGoalsDlg::OnSelchangeObject3()
1279 m_subsys[2] = m_dock2[2] = 0;
1283 void ShipGoalsDlg::OnSelchangeObject4()
1287 m_subsys[3] = m_dock2[3] = 0;
1291 void ShipGoalsDlg::OnSelchangeObject5()
1295 m_subsys[4] = m_dock2[4] = 0;
1299 void ShipGoalsDlg::OnSelchangeObject6()
1303 m_subsys[5] = m_dock2[5] = 0;
1307 void ShipGoalsDlg::OnSelchangeObject7()
1311 m_subsys[6] = m_dock2[6] = 0;
1315 void ShipGoalsDlg::OnSelchangeObject8()
1319 m_subsys[7] = m_dock2[7] = 0;
1323 void ShipGoalsDlg::OnSelchangeObject9()
1327 m_subsys[8] = m_dock2[8] = 0;
1331 void ShipGoalsDlg::OnSelchangeObject10()
1335 m_subsys[9] = m_dock2[9] = 0;
1339 void ShipGoalsDlg::set_object(int item)
1342 int i = 0, z, num, not_used, mode;
1343 ship_subsys *subsys;
1345 if (m_behavior[item] > 0) {
1346 mode = m_behavior_box[item] -> GetItemData(m_behavior[item]);
1347 if (!m_object_box[item] -> GetCount())
1348 m_behavior[item] = m_data[item] = 0;
1350 m_data[item] = m_object_box[item] -> GetItemData(m_object[item]);
1352 if ((mode == AI_GOAL_DOCK) && (m_data[item] >= 0)) {
1353 num = get_docking_list(Ships[m_data[item] & DATA_MASK].modelnum);
1354 m_dock2_box[item] -> EnableWindow(TRUE);
1355 m_dock2_box[item] -> ResetContent();
1356 for (i=0; i<num; i++) {
1357 Assert(Docking_bay_list[i]);
1358 z = m_dock2_box[item] -> AddString(Docking_bay_list[i]);
1359 str = ai_get_goal_ship_name(Docking_bay_list[i], ¬_used);
1360 m_dock2_box[item] -> SetItemDataPtr(z, str);
1363 } else if ((mode == AI_GOAL_DESTROY_SUBSYSTEM) && (m_data[item] >= 0)) {
1364 if (((m_data[item] & TYPE_MASK) == TYPE_SHIP) || ((m_data[item] & TYPE_MASK) == TYPE_PLAYER)) {
1365 i = m_data[item] & DATA_MASK;
1370 m_subsys_box[item] -> ResetContent();
1371 subsys = GET_FIRST(&Ships[i].subsys_list);
1373 while (subsys != END_OF_LIST(&Ships[i].subsys_list)) {
1374 m_subsys_box[item]->AddString(subsys->system_info->subobj_name);
1375 m_subsys_box[item]->SetItemDataPtr(z, subsys->system_info->subobj_name);
1377 subsys = GET_NEXT(subsys);