mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
The ship editor, wing editor, waypoint path dialog, and jump node
dialog all had near-identical code to check whether a new name
conflicts with an existing ship, wing, waypoint path, jump node, or
target priority group (or is empty, or begins with '<'). Both FRED2
and qtFRED carried their own copies of this logic.
Extract it into a single check_name_conflict() function in
code/missioneditor/common.cpp, shared by both editors, and replace the
duplicated validation at each call site with a one-line call:
- FRED2: shipeditordlg, wing_editor, waypointpathdlg, jumpnodedlg
- qtFRED: ShipEditorDialogModel, WaypointEditorDialogModel,
JumpNodeEditorDialogModel, and Editor::validate_wing_name
This also aligns a few small behavioral differences that had crept in
between the two editors: the waypoint and jump node dialogs now skip
empty wing slots (wave_count == 0) when checking for wing-name
collisions, and the qtFRED wing editor now rejects names beginning
with '<'.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
229 lines
5.3 KiB
C++
229 lines
5.3 KiB
C++
/*
|
|
* 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 "FREDDoc.h"
|
|
#include "WaypointPathDlg.h"
|
|
#include "Management.h"
|
|
#include "MainFrm.h"
|
|
#include "object/object.h"
|
|
#include "object/waypoint.h"
|
|
#include "globalincs/linklist.h"
|
|
#include "ai/aigoals.h"
|
|
|
|
#define ID_JUMP_NODE_MENU 8000
|
|
#define ID_WAYPOINT_MENU 9000
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// waypoint_path_dlg dialog
|
|
|
|
waypoint_path_dlg::waypoint_path_dlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(waypoint_path_dlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(waypoint_path_dlg)
|
|
m_name = _T("");
|
|
//}}AFX_DATA_INIT
|
|
bypass_errors = 0;
|
|
}
|
|
|
|
void waypoint_path_dlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(waypoint_path_dlg)
|
|
DDX_Text(pDX, IDC_NAME, m_name);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(waypoint_path_dlg, CDialog)
|
|
//{{AFX_MSG_MAP(waypoint_path_dlg)
|
|
ON_WM_CLOSE()
|
|
ON_WM_INITMENU()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// waypoint_path_dlg message handlers
|
|
|
|
BOOL waypoint_path_dlg::Create()
|
|
{
|
|
BOOL r;
|
|
r = CDialog::Create(IDD, Fred_main_wnd);
|
|
initialize_data(1);
|
|
return r;
|
|
}
|
|
|
|
void waypoint_path_dlg::OnInitMenu(CMenu* pMenu)
|
|
{
|
|
int i;
|
|
SCP_vector<waypoint_list>::iterator ii;
|
|
CMenu *m;
|
|
|
|
m = pMenu->GetSubMenu(0);
|
|
clear_menu(m);
|
|
|
|
for (i = 0, ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++i, ++ii) {
|
|
m->AppendMenu(MF_ENABLED | MF_STRING, ID_WAYPOINT_MENU + i, ii->get_name());
|
|
}
|
|
|
|
m->DeleteMenu(ID_PLACEHOLDER, MF_BYCOMMAND);
|
|
if (cur_waypoint_list != NULL)
|
|
{
|
|
int index = find_index_of_waypoint_list(cur_waypoint_list);
|
|
Assert(index >= 0);
|
|
m->CheckMenuItem(ID_WAYPOINT_MENU + index, MF_BYCOMMAND | MF_CHECKED);
|
|
}
|
|
|
|
CDialog::OnInitMenu(pMenu);
|
|
}
|
|
|
|
void waypoint_path_dlg::OnOK()
|
|
{
|
|
}
|
|
|
|
void waypoint_path_dlg::OnClose()
|
|
{
|
|
if (update_data()) {
|
|
SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
|
|
bypass_errors = 0;
|
|
return;
|
|
}
|
|
|
|
SetWindowPos(Fred_main_wnd, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
|
|
Fred_main_wnd->SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
|
|
}
|
|
|
|
void waypoint_path_dlg::initialize_data(int full_update)
|
|
{
|
|
int enable = TRUE;
|
|
|
|
if (!GetSafeHwnd())
|
|
return;
|
|
|
|
if (query_valid_object() && Objects[cur_object_index].type == OBJ_WAYPOINT)
|
|
{
|
|
Assert(cur_waypoint_list == find_waypoint_list_with_instance(Objects[cur_object_index].instance));
|
|
}
|
|
|
|
if (cur_waypoint_list != NULL) {
|
|
m_name = _T(cur_waypoint_list->get_name());
|
|
|
|
} else {
|
|
m_name = _T("");
|
|
enable = FALSE;
|
|
}
|
|
|
|
if (full_update)
|
|
UpdateData(FALSE);
|
|
|
|
GetDlgItem(IDC_NAME)->EnableWindow(enable);
|
|
}
|
|
|
|
int waypoint_path_dlg::update_data(int redraw)
|
|
{
|
|
int z;
|
|
|
|
if (!GetSafeHwnd())
|
|
return 0;
|
|
|
|
UpdateData(TRUE);
|
|
UpdateData(TRUE);
|
|
|
|
int waypoint_list_index = -1;
|
|
if (query_valid_object() && Objects[cur_object_index].type == OBJ_WAYPOINT)
|
|
{
|
|
waypoint_list_index = calc_waypoint_list_index(Objects[cur_object_index].instance);
|
|
Assert(cur_waypoint_list == &Waypoint_lists[waypoint_list_index]);
|
|
}
|
|
else if (cur_waypoint_list != nullptr)
|
|
{
|
|
Assertion(false, "inconsistent state in waypoint editor!");
|
|
return 0;
|
|
}
|
|
|
|
if (cur_waypoint_list != NULL) {
|
|
m_name.TrimLeft();
|
|
m_name.TrimRight();
|
|
|
|
SCP_string conflict = check_name_conflict("waypoint path", m_name, -1, -1, waypoint_list_index);
|
|
if (!conflict.empty()) {
|
|
if (bypass_errors)
|
|
return 1;
|
|
|
|
bypass_errors = 1;
|
|
CString msg;
|
|
msg.Format("%s\nPress OK to restore old name", conflict.c_str());
|
|
z = MessageBox(msg, "Error", MB_ICONEXCLAMATION | MB_OKCANCEL);
|
|
|
|
if (z == IDCANCEL)
|
|
return -1;
|
|
|
|
m_name = _T(cur_waypoint_list->get_name());
|
|
UpdateData(FALSE);
|
|
}
|
|
|
|
char old_name[NAME_LENGTH];
|
|
strcpy_s(old_name, cur_waypoint_list->get_name());
|
|
cur_waypoint_list->set_name((LPCTSTR) m_name);
|
|
auto str = cur_waypoint_list->get_name();
|
|
if (strcmp(old_name, str)) {
|
|
set_modified(TRUE);
|
|
update_sexp_references(old_name, str);
|
|
ai_update_goal_references(sexp_ref_type::WAYPOINT_PATH, old_name, str);
|
|
|
|
for (auto &wpt: cur_waypoint_list->get_waypoints()) {
|
|
char old_buf[NAME_LENGTH];
|
|
char new_buf[NAME_LENGTH];
|
|
waypoint_stuff_name(old_buf, old_name, wpt.get_index() + 1);
|
|
waypoint_stuff_name(new_buf, str, wpt.get_index() + 1);
|
|
update_sexp_references(old_buf, new_buf);
|
|
ai_update_goal_references(sexp_ref_type::WAYPOINT, old_buf, new_buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (redraw)
|
|
update_map_window();
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL waypoint_path_dlg::OnCommand(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
int id, point;
|
|
object *ptr;
|
|
|
|
id = LOWORD(wParam);
|
|
if ((id >= ID_WAYPOINT_MENU) && (id < ID_WAYPOINT_MENU + (int) Waypoint_lists.size())) {
|
|
if (!update_data()) {
|
|
point = id - ID_WAYPOINT_MENU;
|
|
unmark_all();
|
|
ptr = GET_FIRST(&obj_used_list);
|
|
while (ptr != END_OF_LIST(&obj_used_list)) {
|
|
if (ptr->type == OBJ_WAYPOINT)
|
|
if (calc_waypoint_list_index(ptr->instance) == point)
|
|
mark_object(OBJ_INDEX(ptr));
|
|
|
|
ptr = GET_NEXT(ptr);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return CDialog::OnCommand(wParam, lParam);
|
|
}
|