/* * Copyright (C) Volition, Inc. 1999. All rights reserved. * * All source code herein is the property of Volition, Inc. You may not sell * or otherwise commercially exploit the source or things you created based on the * source. * */ #include "stdafx.h" #include "FRED.h" #include "ShipGoalsDlg.h" #include "object/object.h" #include "globalincs/linklist.h" #include "Management.h" #include "ai/aigoals.h" #include "FREDDoc.h" #include "FREDView.h" #define TYPE_PATH 0x1000 #define TYPE_SHIP 0x2000 #define TYPE_PLAYER 0x3000 #define TYPE_WING 0x4000 #define TYPE_WAYPOINT 0x5000 #define TYPE_MASK 0xf000 #define DATA_MASK 0x0fff #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // ShipGoalsDlg dialog ShipGoalsDlg::ShipGoalsDlg(CWnd* pParent /*=NULL*/) : CDialog(ShipGoalsDlg::IDD, pParent) { int i; for (i=0; i= 0) { // editing orders for just one ship for (i=0; i= 0) { // editing orders for just one wing for (i=0; itype == OBJ_SHIP) || (ptr->type == OBJ_START)) && (ptr->flags & OF_MARKED)){ for (i=0; iinstance, Ai_goal_list[i].def)){ valid[i] = 0; } } } ptr = GET_NEXT(ptr); } } if (Waypoint_lists.empty()) { for (i=0; itype == OBJ_SHIP) || (ptr->type == OBJ_START)) { i = ptr->instance; if ((self_ship > 0) && (self_ship != i) && ship_docking_valid(self_ship, i)){ z = 1; } } ptr = GET_NEXT(ptr); } if (!z){ for (i=0; i ResetContent(); z = m_behavior_box[i] -> AddString("None"); m_behavior_box[i] -> SetItemData(z, (DWORD) AI_GOAL_NONE); for (j=0; j AddString(Ai_goal_list[j].name); m_behavior_box[i] -> SetItemData(z, (DWORD) Ai_goal_list[j].def); } } } if (self_ship >= 0){ initialize(Ai_info[Ships[self_ship].ai_index].goals, self_ship); } else if (self_wing >= 0){ initialize(Wings[self_wing].ai_goals); } else { initialize_multi(); } for (i=0; i SetRange(0, MAX_EDITOR_GOAL_PRIORITY); ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN2)) -> SetRange(0, MAX_EDITOR_GOAL_PRIORITY); ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN3)) -> SetRange(0, MAX_EDITOR_GOAL_PRIORITY); ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN4)) -> SetRange(0, MAX_EDITOR_GOAL_PRIORITY); ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN5)) -> SetRange(0, MAX_EDITOR_GOAL_PRIORITY); ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN6)) -> SetRange(0, MAX_EDITOR_GOAL_PRIORITY); ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN7)) -> SetRange(0, MAX_EDITOR_GOAL_PRIORITY); ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN8)) -> SetRange(0, MAX_EDITOR_GOAL_PRIORITY); ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN9)) -> SetRange(0, MAX_EDITOR_GOAL_PRIORITY); ((CSpinButtonCtrl *) GetDlgItem(IDC_SPIN10)) -> SetRange(0, MAX_EDITOR_GOAL_PRIORITY); return TRUE; } void ShipGoalsDlg::initialize_multi() { int i, flag = 0; object *ptr; int behavior[ED_MAX_GOALS]; int priority[ED_MAX_GOALS]; int subsys[ED_MAX_GOALS]; int dock2[ED_MAX_GOALS]; int data[ED_MAX_GOALS]; ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if (((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) && (ptr->flags & OF_MARKED)) { initialize(Ai_info[Ships[ptr->instance].ai_index].goals, ptr->instance); if (!flag) { flag = 1; for (i=0; i MAX_EDITOR_GOAL_PRIORITY){ m_priority[item] = 50; } m_behavior[item] = 0; if (mode != AI_GOAL_NONE) { i = m_behavior_box[item] -> GetCount(); while (i-- > 0){ if (mode & (m_behavior_box[item]->GetItemData(i))) { m_behavior[item] = i; break; } } } switch (mode) { case AI_GOAL_NONE: case AI_GOAL_CHASE_ANY: case AI_GOAL_UNDOCK: case AI_GOAL_KEEP_SAFE_DISTANCE: case AI_GOAL_PLAY_DEAD: case AI_GOAL_WARP: continue; case AI_GOAL_STAY_STILL: flag = 9; // target is a ship or a waypoint break; case AI_GOAL_CHASE: case AI_GOAL_GUARD: case AI_GOAL_DISABLE_SHIP: case AI_GOAL_DISARM_SHIP: case AI_GOAL_IGNORE: case AI_GOAL_IGNORE_NEW: case AI_GOAL_EVADE_SHIP: case AI_GOAL_STAY_NEAR_SHIP: break; case AI_GOAL_WAYPOINTS: case AI_GOAL_WAYPOINTS_ONCE: flag = 4; // target is a waypoint break; case AI_GOAL_DESTROY_SUBSYSTEM: num = ship_name_lookup(goalp[item].target_name, 1); if (num != -1) m_subsys[item] = ship_get_subsys_index(&Ships[num], goalp[item].docker.name, 1); break; case AI_GOAL_DOCK: m_subsys[item] = -1; num = get_docking_list(Ship_info[Ships[ship].ship_info_index].model_num); for (i=0; itype == OBJ_SHIP) || (ptr->type == OBJ_START)) { inst = ptr->instance; if (ptr->type == OBJ_SHIP) { Assert(inst >= 0 && inst < MAX_SHIPS); if (!stricmp(goalp[item].target_name, Ships[inst].ship_name)) { m_data[item] = inst | TYPE_SHIP; break; } } else { Assert(inst >= 0 && inst < MAX_SHIPS); if (!stricmp(goalp[item].target_name, Ships[inst].ship_name)) { m_data[item] = inst | TYPE_PLAYER; break; } } } ptr = GET_NEXT(ptr); } } if (flag & 0x2) { for (i=0; i::iterator ii; for (i = 0, ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++i, ++ii) { if (!stricmp(goalp[item].target_name, ii->get_name())) { m_data[item] = i | TYPE_PATH; break; } } } if (flag & 0x8) { // data is a waypoint name waypoint *wpt = find_matching_waypoint(goalp[item].target_name); if (wpt != NULL) m_data[item] = wpt->get_objnum() | TYPE_WAYPOINT; } switch (mode) { case AI_GOAL_DOCK: m_dock2[item] = -1; if (m_data[item]) { num = get_docking_list(Ship_info[Ships[m_data[item] & DATA_MASK].ship_info_index].model_num); for (i=0; i::iterator ii; int i, t, z, num, inst, mode; object *ptr; if (init) m_object[item] = -1; if (item >= MAX_AI_GOALS) m_behavior_box[item] -> EnableWindow(FALSE); Assert(item >= 0 && item < ED_MAX_GOALS); m_object_box[item] -> ResetContent(); if (m_behavior[item] < 1) { m_object_box[item] -> EnableWindow(FALSE); m_subsys_box[item] -> EnableWindow(FALSE); m_dock2_box[item] -> EnableWindow(FALSE); m_priority_box[item] -> EnableWindow(FALSE); m_subsys[item] = -1; m_dock2[item] = -1; return; } mode = m_behavior_box[item] -> GetItemData(m_behavior[item]); m_priority_box[item] -> EnableWindow(TRUE); 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) ) { m_object_box[item] -> EnableWindow(FALSE); m_subsys_box[item] -> EnableWindow(FALSE); m_dock2_box[item] -> EnableWindow(FALSE); m_subsys[item] = -1; m_dock2[item] = -1; return; } m_object_box[item] -> EnableWindow(TRUE); switch (mode) { case AI_GOAL_WAYPOINTS: case AI_GOAL_WAYPOINTS_ONCE: //case AI_GOAL_WARP: for (i = 0, ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++i, ++ii) { z = m_object_box[item] -> AddString(ii->get_name()); m_object_box[item] -> SetItemData(z, i | TYPE_PATH); if (init && (m_data[item] == (i | TYPE_PATH))) m_object[item] = z; } break; case AI_GOAL_STAY_STILL: ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if (ptr->type == OBJ_WAYPOINT) { t = TYPE_SHIP; z = m_object_box[item] -> AddString(object_name(OBJ_INDEX(ptr))); m_object_box[item] -> SetItemData(z, OBJ_INDEX(ptr) | TYPE_WAYPOINT); if (init && (m_data[item] == (OBJ_INDEX(ptr) | TYPE_WAYPOINT))) m_object[item] = z; } ptr = GET_NEXT(ptr); } break; } switch (mode) { case AI_GOAL_DESTROY_SUBSYSTEM: case AI_GOAL_CHASE | AI_GOAL_CHASE_WING: case AI_GOAL_DOCK: case AI_GOAL_GUARD | AI_GOAL_GUARD_WING: case AI_GOAL_DISABLE_SHIP: case AI_GOAL_DISARM_SHIP: case AI_GOAL_EVADE_SHIP: case AI_GOAL_IGNORE: case AI_GOAL_IGNORE_NEW: case AI_GOAL_STAY_NEAR_SHIP: case AI_GOAL_STAY_STILL: ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) { inst = ptr->instance; if (ptr->type == OBJ_SHIP) t = TYPE_SHIP; else t = TYPE_PLAYER; Assert(inst >= 0 && inst < MAX_SHIPS); // remove all marked ships from list if (!goalp && (ptr->flags & OF_MARKED)) inst = -1; // when docking, remove invalid dock targets else if (mode == AI_GOAL_DOCK) { if (self_ship < 0 || !ship_docking_valid(self_ship, inst)) inst = -1; } // disallow ship being its own target if (inst >= 0 && inst != self_ship) { z = m_object_box[item] -> AddString(Ships[inst].ship_name); m_object_box[item] -> SetItemData(z, inst | t); if (init && (m_data[item] == (inst | t))) m_object[item] = z; } } ptr = GET_NEXT(ptr); } break; } switch (mode) { case AI_GOAL_CHASE | AI_GOAL_CHASE_WING: case AI_GOAL_GUARD | AI_GOAL_GUARD_WING: for (i=0; i AddString(Wings[i].name); m_object_box[item] -> SetItemData(z, i | TYPE_WING); if (init && (m_data[item] == (i | TYPE_WING))) m_object[item] = z; } break; } if (mode == AI_GOAL_DESTROY_SUBSYSTEM) { m_subsys_box[item] -> EnableWindow(TRUE); m_dock2_box[item] -> EnableWindow(FALSE); m_dock2[item] = -1; set_object(item); if (!m_behavior[item]) set_item(item, init); } else if (mode == AI_GOAL_DOCK) { num = get_docking_list(Ship_info[Ships[cur_ship].ship_info_index].model_num); m_subsys_box[item] -> EnableWindow(TRUE); m_subsys_box[item] -> ResetContent(); for (i=0; i AddString(Docking_bay_list[i]); m_subsys_box[item] -> SetItemDataPtr(z, Docking_bay_list[i]); } set_object(item); if (!m_behavior[item]) set_item(item, init); } else { m_subsys_box[item] -> EnableWindow(FALSE); m_dock2_box[item] -> EnableWindow(FALSE); m_subsys[item] = -1; m_dock2[item] = -1; } } void ShipGoalsDlg::OnSelchangeBehavior1() { UpdateData(TRUE); m_object[0] = 0; m_subsys[0] = m_dock2[0] = 0; set_item(0); UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeBehavior2() { UpdateData(TRUE); m_object[1] = 0; set_item(1); m_subsys[1] = m_dock2[1] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeBehavior3() { UpdateData(TRUE); m_object[2] = 0; set_item(2); m_subsys[2] = m_dock2[2] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeBehavior4() { UpdateData(TRUE); m_object[3] = 0; set_item(3); m_subsys[3] = m_dock2[3] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeBehavior5() { UpdateData(TRUE); m_object[4] = 0; set_item(4); m_subsys[4] = m_dock2[4] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeBehavior6() { UpdateData(TRUE); m_object[5] = 0; set_item(5); m_subsys[5] = m_dock2[5] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeBehavior7() { UpdateData(TRUE); m_object[6] = 0; set_item(6); m_subsys[6] = m_dock2[6] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeBehavior8() { UpdateData(TRUE); m_object[7] = 0; set_item(7); m_subsys[7] = m_dock2[7] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeBehavior9() { UpdateData(TRUE); m_object[8] = 0; set_item(8); m_subsys[8] = m_dock2[8] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeBehavior10() { UpdateData(TRUE); m_object[9] = 0; set_item(9); m_subsys[9] = m_dock2[9] = 0; UpdateData(FALSE); } void ShipGoalsDlg::update() { int i; if (goalp) { for (i=0; itype == OBJ_SHIP) || (ptr->type == OBJ_START)) && (ptr->flags & OF_MARKED)) { goalp = Ai_info[Ships[ptr->instance].ai_index].goals; for (i=0; itype == OBJ_SHIP) || (ptr->type == OBJ_START)) && (ptr->flags & OF_MARKED)) { self_ship = ptr->instance; goalp = Ai_info[Ships[self_ship].ai_index].goals; verify_orders(self_ship); } ptr = GET_NEXT(ptr); } } } int ShipGoalsDlg::verify_orders(int ship) { char *str, buf[2048]; if ((str = error_check_initial_orders(goalp, self_ship, self_wing))!=NULL) { if (*str == '!') return 1; else if (*str == '*') str++; if (ship >= 0) sprintf(buf, "Initial orders error for ship \"%s\"\n\n%s", Ships[ship].ship_name, str); else strcpy_s(buf, str); if (MessageBox(buf, "Error", MB_OKCANCEL | MB_ICONEXCLAMATION) != IDOK) return 1; } return 0; } void ShipGoalsDlg::update_item(int item, int multi) { char *docker, *dockee, *subsys; int mode; char buf[512], save[80]; waypoint_list *wp_list; if (item >= MAX_AI_GOALS) return; if (!multi || m_priority[item] >= 0) goalp[item].priority = m_priority[item]; if (m_behavior[item] < 0) { if (multi) return; else m_behavior[item] = 0; } mode = m_behavior_box[item] -> GetItemData(m_behavior[item]); switch (mode) { case AI_GOAL_NONE: case AI_GOAL_CHASE_ANY: case AI_GOAL_UNDOCK: case AI_GOAL_KEEP_SAFE_DISTANCE: case AI_GOAL_PLAY_DEAD: case AI_GOAL_WARP: MODIFY(goalp[item].ai_mode, mode); return; case AI_GOAL_WAYPOINTS: case AI_GOAL_WAYPOINTS_ONCE: case AI_GOAL_DISABLE_SHIP: case AI_GOAL_DISARM_SHIP: case AI_GOAL_IGNORE: case AI_GOAL_IGNORE_NEW: case AI_GOAL_EVADE_SHIP: case AI_GOAL_STAY_NEAR_SHIP: case AI_GOAL_STAY_STILL: break; case AI_GOAL_DESTROY_SUBSYSTEM: subsys = NULL; if (!multi || (m_data[item] && (m_subsys[item] >= 0))) subsys = (char *) m_subsys_box[item]->GetItemDataPtr(m_subsys[item]); //MODIFY(goalp[item].ai_submode, m_subsys[item] + 1); if (!subsys) { sprintf(buf, "Order #%d doesn't have valid subsystem name. Order will be removed", item + 1); MessageBox(buf, "Notice"); MODIFY(goalp[item].ai_mode, AI_GOAL_NONE); return; } else { if (!goalp[item].docker.name || (goalp[item].docker.name && !stricmp(goalp[item].docker.name, subsys))) set_modified(); goalp[item].docker.name = subsys; } break; case AI_GOAL_CHASE | AI_GOAL_CHASE_WING: switch (m_data[item] & TYPE_MASK) { case TYPE_SHIP: case TYPE_PLAYER: mode = AI_GOAL_CHASE; break; case TYPE_WING: mode = AI_GOAL_CHASE_WING; break; } break; case AI_GOAL_DOCK: docker = NULL; if (!multi || (m_data[item] && (m_subsys[item] >= 0))) docker = (char *) m_subsys_box[item] -> GetItemDataPtr(m_subsys[item]); dockee = NULL; if (!multi || (m_data[item] && (m_dock2[item] >= 0))) dockee = (char *) m_dock2_box[item] -> GetItemDataPtr(m_dock2[item]); if (docker == (char *) 0xffffffff) docker = NULL; if (dockee == (char *) 0xffffffff) dockee = NULL; if (!docker || !dockee) { sprintf(buf, "Order #%d doesn't have valid docking points. Order will be removed", item + 1); MessageBox(buf, "Notice"); MODIFY(goalp[item].ai_mode, AI_GOAL_NONE); return; } else { if (!goalp[item].docker.name) set_modified(); else if (!stricmp(goalp[item].docker.name, docker)) set_modified(); if (!goalp[item].dockee.name) set_modified(); else if (!stricmp(goalp[item].dockee.name, dockee)) set_modified(); goalp[item].docker.name = docker; goalp[item].dockee.name = dockee; } break; case AI_GOAL_GUARD | AI_GOAL_GUARD_WING: switch (m_data[item] & TYPE_MASK) { case TYPE_SHIP: case TYPE_PLAYER: mode = AI_GOAL_GUARD; break; case TYPE_WING: mode = AI_GOAL_GUARD_WING; break; } break; default: Warning(LOCATION, "Unknown AI_GOAL type 0x%x", mode); MODIFY(goalp[item].ai_mode, AI_GOAL_NONE); return; } MODIFY(goalp[item].ai_mode, mode); *save = 0; if (goalp[item].target_name) strcpy_s(save, goalp[item].target_name); switch (m_data[item] & TYPE_MASK) { int not_used; case TYPE_SHIP: case TYPE_PLAYER: goalp[item].target_name = ai_get_goal_target_name(Ships[m_data[item] & DATA_MASK].ship_name, ¬_used); break; case TYPE_WING: goalp[item].target_name = ai_get_goal_target_name(Wings[m_data[item] & DATA_MASK].name, ¬_used); break; case TYPE_PATH: wp_list = find_waypoint_list_at_index(m_data[item] & DATA_MASK); Assert(wp_list != NULL); goalp[item].target_name = ai_get_goal_target_name(wp_list->get_name(), ¬_used); break; case TYPE_WAYPOINT: goalp[item].target_name = ai_get_goal_target_name(object_name(m_data[item] & DATA_MASK), ¬_used); break; case 0: case -1: case (-1 & TYPE_MASK): if (multi) return; sprintf(buf, "Order #%d doesn't have a valid target. Order will be removed", item + 1); MessageBox(buf, "Notice"); MODIFY(goalp[item].ai_mode, AI_GOAL_NONE); return; default: Assert(0); } if (stricmp(save, goalp[item].target_name)) set_modified(); } void ShipGoalsDlg::OnOK() { int i, mode; UpdateData(TRUE); for (i=0; i GetItemData(m_behavior[i]); 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) ) { if (!m_object_box[i] -> GetCount()) // no valid objects? m_behavior[i] = 0; else m_data[i] = m_object_box[i] -> GetItemData(m_object[i]); } } update(); CDialog::OnOK(); } void ShipGoalsDlg::OnSelchangeObject1() { UpdateData(TRUE); set_object(0); m_subsys[0] = m_dock2[0] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeObject2() { UpdateData(TRUE); set_object(1); m_subsys[1] = m_dock2[1] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeObject3() { UpdateData(TRUE); set_object(2); m_subsys[2] = m_dock2[2] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeObject4() { UpdateData(TRUE); set_object(3); m_subsys[3] = m_dock2[3] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeObject5() { UpdateData(TRUE); set_object(4); m_subsys[4] = m_dock2[4] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeObject6() { UpdateData(TRUE); set_object(5); m_subsys[5] = m_dock2[5] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeObject7() { UpdateData(TRUE); set_object(6); m_subsys[6] = m_dock2[6] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeObject8() { UpdateData(TRUE); set_object(7); m_subsys[7] = m_dock2[7] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeObject9() { UpdateData(TRUE); set_object(8); m_subsys[8] = m_dock2[8] = 0; UpdateData(FALSE); } void ShipGoalsDlg::OnSelchangeObject10() { UpdateData(TRUE); set_object(9); m_subsys[9] = m_dock2[9] = 0; UpdateData(FALSE); } void ShipGoalsDlg::set_object(int item) { char *str; int i = 0, z, num, not_used, mode; ship_subsys *subsys; if (m_behavior[item] > 0) { mode = m_behavior_box[item] -> GetItemData(m_behavior[item]); if (!m_object_box[item] -> GetCount()) m_behavior[item] = m_data[item] = 0; else m_data[item] = m_object_box[item] -> GetItemData(m_object[item]); if ((mode == AI_GOAL_DOCK) && (m_data[item] >= 0)) { num = get_docking_list(Ship_info[Ships[m_data[item] & DATA_MASK].ship_info_index].model_num); m_dock2_box[item] -> EnableWindow(TRUE); m_dock2_box[item] -> ResetContent(); for (i=0; i AddString(Docking_bay_list[i]); str = ai_get_goal_target_name(Docking_bay_list[i], ¬_used); m_dock2_box[item] -> SetItemDataPtr(z, str); } } else if ((mode == AI_GOAL_DESTROY_SUBSYSTEM) && (m_data[item] >= 0)) { if (((m_data[item] & TYPE_MASK) == TYPE_SHIP) || ((m_data[item] & TYPE_MASK) == TYPE_PLAYER)) { i = m_data[item] & DATA_MASK; } else Int3(); m_subsys_box[item] -> ResetContent(); subsys = GET_FIRST(&Ships[i].subsys_list); z = 0; while (subsys != END_OF_LIST(&Ships[i].subsys_list)) { m_subsys_box[item]->AddString(subsys->system_info->subobj_name); m_subsys_box[item]->SetItemDataPtr(z, subsys->system_info->subobj_name); z++; subsys = GET_NEXT(subsys); } } } }