Descent3/legacy/editor/PathPadDialog.cpp

1112 lines
26 KiB
C++
Raw Normal View History

/*
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// PathPadDialog.cpp : implementation file
//
#include "stdafx.h"
#include "editor.h"
#include "PathPadDialog.h"
#include "EditLineDialog.h"
#include "epath.h"
#include "object.h"
#include "room.h"
#include "FindIntersection.h"
#include "ebnode.h"
#include "boa.h"
#include "object.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPathPadDialog dialog
CPathPadDialog::CPathPadDialog(CWnd* pParent /*=NULL*/)
: CKeypadDialog(CPathPadDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CPathPadDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CPathPadDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPathPadDialog)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CPathPadDialog, CDialog)
//{{AFX_MSG_MAP(CPathPadDialog)
ON_EN_KILLFOCUS(IDC_CURRENT_NODE_EDIT, OnKillfocusCurrentNodeEdit)
ON_BN_CLICKED(IDC_PATHPAD_ADD_PATH, OnPathpadAddPath)
ON_BN_CLICKED(IDC_PATHPAD_INSERT_NODE, OnPathpadInsertNode)
ON_BN_CLICKED(IDC_PATHPAD_DELETE_NODE, OnPathpadDeleteNode)
ON_BN_CLICKED(IDC_PATHPAD_MOVE_FORWARD, OnPathpadMoveForward)
ON_BN_CLICKED(IDC_PATHPAD_MOVE_BACKWARD, OnPathpadMoveBackward)
ON_BN_CLICKED(IDC_PATHPAD_MOVE_LEFT, OnPathpadMoveLeft)
ON_BN_CLICKED(IDC_PATHPAD_MOVE_RIGHT, OnPathpadMoveRight)
ON_CBN_SELENDOK(IDC_PATHPAD_PULLDOWN, OnSelendokPathpadPulldown)
ON_BN_CLICKED(IDC_PATHPAD_CENTER_VIEW, OnPathpadCenterView)
ON_BN_CLICKED(IDC_PATHPAD_MOVE_DOWN, OnPathpadMoveDown)
ON_BN_CLICKED(IDC_PATHPAD_MOVE_UP, OnPathpadMoveUp)
ON_BN_CLICKED(IDC_PATHPAD_PREV_NODE, OnPathpadPrevNode)
ON_BN_CLICKED(IDC_PATHPAD_NEXT_NODE, OnPathpadNextNode)
ON_BN_CLICKED(IDC_DELETE_PATH, OnDeletePath)
ON_BN_CLICKED(IDC_SHOW_NODES_CHECK, OnShowNodesCheck)
ON_WM_HELPINFO()
ON_BN_CLICKED(IDC_PATH_MOVE_OBJECT_BUTTON, OnPathMoveObjectButton)
ON_BN_CLICKED(IDC_PATH_REORIENT_VIEWER_BUTTON, OnPathReorientViewerButton)
ON_EN_KILLFOCUS(IDC_PATH_INC_TEXT, OnKillfocusPathIncText)
ON_WM_PAINT()
ON_BN_CLICKED(IDC_PATH_MOVE_NODE_TO_CURRENT_OBJECT, OnPathMoveNodeToCurrentObject)
ON_BN_CLICKED(IDC_PATH_MOVE_OBJ_NO_ORIENT, OnPathMoveObjNoOrient)
ON_BN_CLICKED(IDC_PATH_VERIFY_BUTTON, OnPathVerifyButton)
ON_BN_CLICKED(IDC_AIN_AUTO_EDGE_NODE, OnAinAutoEdgeNode)
ON_BN_CLICKED(IDC_AIN_BACK, OnAinBack)
ON_BN_CLICKED(IDC_AIN_CREATE_NODE_AT_VIEWER, OnAinCreateNodeAtViewer)
ON_BN_CLICKED(IDC_AIN_CREATE_NODES, OnAinCreateNodes)
ON_CBN_SELENDOK(IDC_AIN_CURRENT_NODE, OnSelendokAinCurrentNode)
ON_BN_CLICKED(IDC_AIN_DELETE_EDGE, OnAinDeleteEdge)
ON_BN_CLICKED(IDC_AIN_DELETE_NODE, OnAinDeleteNode)
ON_BN_CLICKED(IDC_AIN_DOWN, OnAinDown)
ON_BN_CLICKED(IDC_AIN_FORWARD, OnAinForward)
ON_BN_CLICKED(IDC_AIN_INSERT_NODE_ON_EDGE, OnAinInsertNodeOnEdge)
ON_BN_CLICKED(IDC_AIN_LEFT, OnAinLeft)
ON_BN_CLICKED(IDC_AIN_MAKE_EDGE, OnAinMakeEdge)
ON_EN_KILLFOCUS(IDC_AIN_MOVE_AMOUNT, OnKillfocusAinMoveAmount)
ON_BN_CLICKED(IDC_AIN_MOVE_NODE_TO_VIEWER, OnAinMoveNodeToViewer)
ON_BN_CLICKED(IDC_AIN_MPNS, OnAinMpns)
ON_CBN_SELENDOK(IDC_AIN_OTHER_NODE, OnSelendokAinOtherNode)
ON_BN_CLICKED(IDC_AIN_RESET_ROOM_NODES, OnAinResetRoomNodes)
ON_BN_CLICKED(IDC_AIN_RIGHT, OnAinRight)
ON_BN_CLICKED(IDC_AIN_SEL_NODE_EDGES, OnAinSelNodeEdges)
ON_BN_CLICKED(IDC_AIN_SEL_ROOM, OnAinSelRoom)
ON_BN_CLICKED(IDC_AIN_UP, OnAinUp)
ON_BN_CLICKED(IDC_AIN_SEL_ROOM_AND_NEXT_ROOMS, OnAinSelRoomAndNextRooms)
ON_BN_CLICKED(IDC_AIN_VERIFY_LEVEL, OnAinVerifyLevel)
ON_BN_CLICKED(IDC_AIN_VERIFY_ROOM, OnAinVerifyRoom)
ON_BN_CLICKED(IDC_AIN_VIEW_ALL_NODES, OnAinViewAllNodes)
ON_BN_CLICKED(IDC_AIN_VIEW_NONE, OnAinViewNone)
ON_BN_CLICKED(IDC_AIN_VIEW_ROOM, OnAinViewRoom)
ON_BN_CLICKED(IDC_AIN_VIEW_ROOM_AND_NEXT_ROOMS, OnAinViewRoomAndNextRooms)
ON_CBN_SETFOCUS(IDC_AIN_CURRENT_NODE, OnSetfocusAinCurrentNode)
ON_CBN_SETFOCUS(IDC_AIN_OTHER_NODE, OnSetfocusAinOtherNode)
ON_BN_CLICKED(IDC_IENAV_BUTTON, OnIenavButton)
ON_BN_CLICKED(IDC_MVTN_BUTTON, OnMvtnButton)
ON_BN_CLICKED(IDC_AER_BUTTON, OnAerButton)
ON_BN_CLICKED(IDC_ONTVGP_BUTTON, OnOntvgpButton)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPathPadDialog message handlers
void CPathPadDialog::OnKillfocusCurrentNodeEdit()
{
CEdit *ebox;
char str[20];
int curpath=D3EditState.current_path;
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
ebox=(CEdit *) GetDlgItem (IDC_CURRENT_NODE_EDIT);
ebox->GetWindowText (str,20);
// Do the base 1 to base 0 conversion
D3EditState.current_node = atoi (str) - 1;
if(D3EditState.current_node >= GamePaths[curpath].num_nodes)
D3EditState.current_node = GamePaths[curpath].num_nodes - 1;
else if(D3EditState.current_node < 0)
D3EditState.current_node = 0;
UpdateDialog();
}
void CPathPadDialog::OnPathpadAddPath()
{
int curnode;
char *namestr;
int pathnum;
int dup_test;
pathnum=AllocGamePath ();
if (pathnum < 0)
{
return;
}
CEditLineDialog dlg ("Enter path name",this);
int ret=dlg.DoModal();
if (ret==IDCANCEL)
{
FreeGamePath(pathnum);
return;
}
namestr=(char *)dlg.GetText ();
dup_test = FindGamePathName(namestr);
if(dup_test != -1)
{
OutrageMessageBox("PATH NOT CREATED: A path named %s already exists.", namestr);
FreeGamePath(pathnum);
return;
}
strcpy (GamePaths[pathnum].name,namestr);
curnode=InsertNodeIntoPath (pathnum,-1,0);
if(curnode < 0) return;
D3EditState.current_path=pathnum;
D3EditState.current_node=curnode;
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadInsertNode()
{
int curpath=D3EditState.current_path;
int curnode=D3EditState.current_node;
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
curnode=InsertNodeIntoPath (curpath,curnode,0);
if(curnode < 0) return;
D3EditState.current_node=curnode;
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadDeleteNode()
{
int curpath=D3EditState.current_path;
int curnode=D3EditState.current_node;
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
if (GamePaths[curpath].num_nodes==1)
{
MessageBox ("This is the only node in this path. If you wish to delete this path, click the 'Delete Path' button.");
return;
}
DeleteNodeFromPath (curpath,curnode);
// If this was the ending node, move it back one
if (curnode==GamePaths[curpath].num_nodes)
D3EditState.current_node=curnode-1;
State_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadMoveForward()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
int p=D3EditState.current_path;
int n=D3EditState.current_node;
vector delta_movement = Viewer_object->orient.fvec * D3EditState.node_movement_inc;
MovePathNode(p, n, &delta_movement);
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadMoveBackward()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
int p=D3EditState.current_path;
int n=D3EditState.current_node;
vector delta_movement = Viewer_object->orient.fvec * -D3EditState.node_movement_inc;
MovePathNode(p, n, &delta_movement);
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadMoveLeft()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
int p=D3EditState.current_path;
int n=D3EditState.current_node;
vector delta_movement = Viewer_object->orient.rvec * -D3EditState.node_movement_inc;
MovePathNode(p, n, &delta_movement);
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadMoveRight()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
int p=D3EditState.current_path;
int n=D3EditState.current_node;
vector delta_movement = Viewer_object->orient.rvec * D3EditState.node_movement_inc;
MovePathNode(p, n, &delta_movement);
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnSelendokPathpadPulldown()
{
int i,cur;
char name[200];
cur=SendDlgItemMessage( IDC_PATHPAD_PULLDOWN, CB_GETCURSEL,0,0);
SendDlgItemMessage( IDC_PATHPAD_PULLDOWN, CB_GETLBTEXT,cur,(LPARAM) (LPCTSTR)name);
i=FindGamePathName (name);
D3EditState.current_path=i;
D3EditState.current_node=0;
State_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadCenterView()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
int p=D3EditState.current_path;
int n=D3EditState.current_node;
game_path *gp=&GamePaths[p];
vector attempted_pos;
vector subvec={0.0,0.0,0.0}; // changed for now
attempted_pos = gp->pathnodes[n].pos - subvec;
fvi_query fq;
fvi_info hit_info;
fq.p0 = &GamePaths[p].pathnodes[n].pos;
fq.startroom = GamePaths[p].pathnodes[n].roomnum;
fq.p1 = &attempted_pos;
fq.rad = 0.0f;
fq.thisobjnum = -1;
fq.ignore_obj_list = NULL;
fq.flags = FQ_TRANSPOINT | FQ_IGNORE_RENDER_THROUGH_PORTALS;
int hit = fvi_FindIntersection(&fq, &hit_info);
if (hit != HIT_NONE)
Int3(); //what does it mean that we hit something?
ObjSetPos(Viewer_object,&hit_info.hit_pnt,hit_info.hit_room,NULL,false);
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadMoveDown()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
int p=D3EditState.current_path;
int n=D3EditState.current_node;
vector delta_movement = Viewer_object->orient.uvec * -D3EditState.node_movement_inc;
MovePathNode(p, n, &delta_movement);
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadMoveUp()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
int p=D3EditState.current_path;
int n=D3EditState.current_node;
vector delta_movement = Viewer_object->orient.uvec * D3EditState.node_movement_inc;
MovePathNode(p, n, &delta_movement);
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadPrevNode()
{
if (Num_game_paths<1)
return;
int p=D3EditState.current_path;
int n=D3EditState.current_node;
n--;
if (n<0)
n=GamePaths[p].num_nodes-1;
D3EditState.current_node=n;
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnPathpadNextNode()
{
if (Num_game_paths<1)
return;
int p=D3EditState.current_path;
int n=D3EditState.current_node;
n++;
n%=GamePaths[p].num_nodes;
D3EditState.current_node=n;
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::UpdateDialog()
{
int n=D3EditState.current_path;
char str[50];
CEdit *ebox;
SendDlgItemMessage( IDC_PATHPAD_PULLDOWN, CB_RESETCONTENT,0,0);
for (int i=0;i<MAX_GAME_PATHS;i++)
{
if (GamePaths[i].used)
SendDlgItemMessage( IDC_PATHPAD_PULLDOWN, CB_ADDSTRING,0,(LPARAM) (LPCTSTR) GamePaths[i].name);
}
SendDlgItemMessage( IDC_PATHPAD_PULLDOWN, CB_SELECTSTRING,0,(LPARAM) (LPCTSTR) GamePaths[n].name);
ebox=(CEdit *) GetDlgItem (IDC_CURRENT_NODE_EDIT);
sprintf (str,"%d",D3EditState.current_node + 1);
ebox->SetWindowText (str);
ebox=(CEdit *) GetDlgItem (IDC_PATH_INC_TEXT);
sprintf (str,"%f",D3EditState.node_movement_inc);
ebox->SetWindowText (str);
if(n < Num_game_paths && D3EditState.current_node < GamePaths[n].num_nodes)
{
ebox=(CEdit *) GetDlgItem (IDC_PATHPAD_CUR_NODE_ROOM);
if(!ROOMNUM_OUTSIDE(GamePaths[n].pathnodes[D3EditState.current_node].roomnum))
sprintf (str,"Current Mine Room: %d",GamePaths[n].pathnodes[D3EditState.current_node].roomnum);
else
sprintf (str,"Current Terrain Cell: %d", (0x7FFFFFFF & GamePaths[n].pathnodes[D3EditState.current_node].roomnum));
ebox->SetWindowText (str);
}
ebox=(CEdit *) GetDlgItem (IDC_PATHPAD_NUM_NODES);
sprintf (str,"Number of nodes: %d",GamePaths[n].num_nodes);
ebox->SetWindowText (str);
CheckDlgButton (IDC_SHOW_NODES_CHECK,Show_paths?1:0);
}
void CPathPadDialog::OnDeletePath()
{
int ret;
int n=D3EditState.current_path;
if (Num_game_paths<1)
return;
ret=MessageBox ("Are you sure you want to delete this path?",GamePaths[n].name,MB_YESNO);
if (ret==IDNO)
return;
FreeGamePath(n);
D3EditState.current_path=GetNextPath(n);
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnShowNodesCheck()
{
int c=IsDlgButtonChecked(IDC_SHOW_NODES_CHECK);
if (c)
Show_paths=1;
else
Show_paths=0;
TV_changed=1;
}
BOOL CPathPadDialog::OnHelpInfo(HELPINFO* pHelpInfo)
{
WinHelp(HID_PATHSTAB,HELP_CONTEXT);
return TRUE;
//return CDialog::OnHelpInfo(pHelpInfo);
}
void CPathPadDialog::OnPathMoveObjectButton()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
if (Cur_object_index != -1) // we have a selected object
{
int p=D3EditState.current_path;
int n=D3EditState.current_node;
game_path *gp=&GamePaths[p];
ObjSetPos(&Objects[Cur_object_index],&gp->pathnodes[n].pos,gp->pathnodes[n].roomnum,NULL,false);
matrix node_orient;
vm_VectorToMatrix(&node_orient, &gp->pathnodes[n].fvec, &gp->pathnodes[n].uvec, NULL);
ObjSetOrient(&Objects[Cur_object_index], &node_orient);
World_changed=1;
}
}
void CPathPadDialog::OnPathReorientViewerButton()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
int p=D3EditState.current_path;
int n=D3EditState.current_node;
game_path *gp=&GamePaths[p];
matrix node_orient;
vm_VectorToMatrix(&node_orient, &gp->pathnodes[n].fvec, &gp->pathnodes[n].uvec, NULL);
ObjSetOrient(Viewer_object, &node_orient);
World_changed=1;
UpdateDialog();
}
void CPathPadDialog::OnKillfocusPathIncText()
{
CEdit *ebox;
char str[20];
ebox=(CEdit *) GetDlgItem (IDC_PATH_INC_TEXT);
ebox->GetWindowText (str,20);
// Do the base 1 to base 0 conversion
sscanf(str, "%f", &D3EditState.node_movement_inc);
if(D3EditState.node_movement_inc <= 0.0f || D3EditState.node_movement_inc > 32000.0f)
D3EditState.node_movement_inc = 1.0f;
UpdateDialog();
}
void CPathPadDialog::OnPaint()
{
CPaintDC dc(this); // device context for painting
UpdateDialog();
}
void CPathPadDialog::OnPathMoveNodeToCurrentObject()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
if (Cur_object_index != -1) // we have a selected object
{
int p=D3EditState.current_path;
int n=D3EditState.current_node;
game_path *gp=&GamePaths[p];
MovePathNodeToPos(p, n, &Objects[Cur_object_index].pos);
World_changed=1;
UpdateDialog();
}
}
void CPathPadDialog::OnPathMoveObjNoOrient()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
if (Cur_object_index != -1) // we have a selected object
{
int p=D3EditState.current_path;
int n=D3EditState.current_node;
game_path *gp=&GamePaths[p];
ObjSetPos(&Objects[Cur_object_index],&gp->pathnodes[n].pos,gp->pathnodes[n].roomnum, NULL, false);
//matrix node_orient;
World_changed=1;
UpdateDialog();
}
}
void CPathPadDialog::OnPathVerifyButton()
{
}
int BNode_current_id = 0;
int BNode_current_room = 0;
int BNode_other_id = 0;
int BNode_other_room = 0;
float BNode_move_amount = 1.0f;
void CPathPadDialog::OnAinAutoEdgeNode()
{
EBNode_AutoEdgeNode(BNode_current_id, BNode_current_room);
EBNode_VerifyGraph();
World_changed = 1;
}
void CPathPadDialog::OnAinBack()
{
vector diff = -Viewer_object->orient.fvec * BNode_move_amount;
EBNode_Move(true, BNode_current_room, BNode_current_id, &diff);
World_changed = 1;
}
void CPathPadDialog::OnAinCreateNodeAtViewer()
{
int node = EBNode_AddNode(Viewer_object->roomnum, &Viewer_object->pos, true, true);
if(node != -1)
{
World_changed = 1;
}
// EBNode_VerifyGraph();
}
void CPathPadDialog::OnAinCreateNodes()
{
MakeBOA();
EBNode_MakeFirstPass();
World_changed = 1;
}
void CPathPadDialog::OnSelendokAinCurrentNode()
{
int cur;
char name[200];
cur=SendDlgItemMessage( IDC_AIN_CURRENT_NODE, CB_GETCURSEL,0,0);
SendDlgItemMessage( IDC_AIN_CURRENT_NODE, CB_GETLBTEXT,cur,(LPARAM) (LPCTSTR)name);
if(sscanf(name, "Room %d, Node %d", &BNode_current_room, &BNode_current_id) != 2)
{
sscanf(name, "Region %d, Node %d", &BNode_current_room, &BNode_current_id);
BNode_current_room += Highest_room_index + 1;
}
BNode_current_id--;
}
void CPathPadDialog::OnAinDeleteEdge()
{
EBNode_RemoveEdge(BNode_current_id, BNode_current_room, BNode_other_id, BNode_other_room);
World_changed = 1;
EBNode_VerifyGraph();
}
void CPathPadDialog::OnAinDeleteNode()
{
EBNode_RemoveNode(BNode_current_room, BNode_current_id);
World_changed = 1;
EBNode_VerifyGraph();
}
void CPathPadDialog::OnAinDown()
{
vector diff = -Viewer_object->orient.uvec * BNode_move_amount;
EBNode_Move(true, BNode_current_room, BNode_current_id, &diff);
World_changed = 1;
}
void CPathPadDialog::OnAinForward()
{
vector diff = Viewer_object->orient.fvec * BNode_move_amount;
EBNode_Move(true, BNode_current_room, BNode_current_id, &diff);
World_changed = 1;
}
void CPathPadDialog::OnAinInsertNodeOnEdge()
{
EBNode_InsertNodeOnEdge(BNode_current_id, BNode_current_room, BNode_other_id, BNode_other_room);
EBNode_VerifyGraph();
World_changed = 1;
}
void CPathPadDialog::OnAinLeft()
{
vector diff = -Viewer_object->orient.rvec * BNode_move_amount;
EBNode_Move(true, BNode_current_room, BNode_current_id, &diff);
World_changed = 1;
}
void CPathPadDialog::OnAinMakeEdge()
{
EBNode_AddEdge(BNode_current_id, BNode_current_room, BNode_other_id, BNode_other_room);
EBNode_VerifyGraph();
World_changed = 1;
}
void CPathPadDialog::OnKillfocusAinMoveAmount()
{
CEdit *ebox;
char str[20];
ebox=(CEdit *) GetDlgItem (IDC_AIN_MOVE_AMOUNT);
ebox->GetWindowText (str,20);
sscanf(str, "%f", &BNode_move_amount);
UpdateDialog();
}
void CPathPadDialog::OnAinMoveNodeToViewer()
{
vector diff = Viewer_object->pos;
EBNode_Move(false, BNode_current_room, BNode_current_id, &diff);
World_changed = 1;
}
void CPathPadDialog::OnAinMpns()
{
// TODO: Add your control notification handler code here
}
void CPathPadDialog::OnSelendokAinOtherNode()
{
int cur;
char name[200];
cur=SendDlgItemMessage( IDC_AIN_OTHER_NODE, CB_GETCURSEL,0,0);
SendDlgItemMessage( IDC_AIN_OTHER_NODE, CB_GETLBTEXT,cur,(LPARAM) (LPCTSTR)name);
if(sscanf(name, "Room %d, Node %d", &BNode_other_room, &BNode_other_id) != 2)
{
sscanf(name, "Region %d, Node %d", &BNode_other_room, &BNode_other_id);
BNode_other_room += Highest_room_index + 1;
}
BNode_other_id--;
}
void CPathPadDialog::OnAinResetRoomNodes()
{
// TODO: Add your control notification handler code here
EBNode_VerifyGraph();
}
void CPathPadDialog::OnAinRight()
{
vector diff = Viewer_object->orient.rvec * BNode_move_amount;
EBNode_Move(true, BNode_current_room, BNode_current_id, &diff);
World_changed = 1;
}
#define EBVIEW_ROOM 1
#define EBVIEW_ROOM_AND_NEXT_ROOMS 2
#define EBVIEW_CUR_EDGES 3
char ENode_view_type = EBVIEW_ROOM;
void CPathPadDialog::OnAinSelNodeEdges()
{
ENode_view_type = EBVIEW_CUR_EDGES;
ResetNodesForComboBox(IDC_AIN_CURRENT_NODE, ENode_view_type);
ResetNodesForComboBox(IDC_AIN_OTHER_NODE ,ENode_view_type);
}
void CPathPadDialog::OnAinSelRoom()
{
ENode_view_type = EBVIEW_ROOM;
ResetNodesForComboBox(IDC_AIN_CURRENT_NODE, ENode_view_type);
ResetNodesForComboBox(IDC_AIN_OTHER_NODE ,ENode_view_type);
}
void CPathPadDialog::OnAinSelRoomAndNextRooms()
{
ENode_view_type = EBVIEW_ROOM_AND_NEXT_ROOMS;
ResetNodesForComboBox(IDC_AIN_CURRENT_NODE, ENode_view_type);
ResetNodesForComboBox(IDC_AIN_OTHER_NODE ,ENode_view_type);
}
void CPathPadDialog::OnAinUp()
{
vector diff = Viewer_object->orient.uvec * BNode_move_amount;
EBNode_Move(true, BNode_current_room, BNode_current_id, &diff);
World_changed = 1;
}
void CPathPadDialog::OnAinVerifyLevel()
{
EBNode_VerifyGraph();
}
void CPathPadDialog::OnAinVerifyRoom()
{
EBNode_ClearLevel();
World_changed = 1;
}
void CPathPadDialog::OnAinViewAllNodes()
{
EBN_draw_type = EBDRAW_LEVEL;
World_changed = 1;
}
void CPathPadDialog::OnAinViewNone()
{
EBN_draw_type = EBDRAW_NONE;
World_changed = 1;
}
void CPathPadDialog::OnAinViewRoom()
{
EBN_draw_type = EBDRAW_ROOM;
World_changed = 1;
}
void CPathPadDialog::OnAinViewRoomAndNextRooms()
{
EBN_draw_type = EBDRAW_ROOM_AND_NEXT_ROOMS;
World_changed = 1;
}
void CPathPadDialog::ResetNodesForComboBox(int handle, char selection_type)
{
char message[25];
SendDlgItemMessage(handle, CB_RESETCONTENT, 0, 0);
bool f_add = false;
int num_next_rooms = 0;
int next_rooms[1000];
if(Viewer_object->roomnum >= 0 && Viewer_object->roomnum <= Highest_room_index && Rooms[Viewer_object->roomnum].used)
{
if(selection_type == EBVIEW_ROOM || selection_type == EBVIEW_ROOM_AND_NEXT_ROOMS)
{
for (int i = 0; i < Rooms[Viewer_object->roomnum].bn_info.num_nodes; i++)
{
f_add = true;
sprintf(message, "Room %d, Node %d", Viewer_object->roomnum, i + 1);
SendDlgItemMessage( handle, CB_ADDSTRING,0,(LPARAM) (LPCTSTR) message);
}
if(selection_type == EBVIEW_ROOM_AND_NEXT_ROOMS)
{
int i;
int j;
int k;
for(i = 0; i < Rooms[Viewer_object->roomnum].num_portals; i++)
{
bool f_found = false;
for(j = 0; j < num_next_rooms; j++)
{
if(next_rooms[j] == Rooms[Viewer_object->roomnum].portals[i].croom)
{
f_found = true;
break;
}
}
if(!f_found &&
Rooms[Viewer_object->roomnum].portals[i].croom >= 0 &&
!(Rooms[Rooms[Viewer_object->roomnum].portals[i].croom].flags & RF_EXTERNAL))
{
for(k = 0; k < Rooms[Rooms[Viewer_object->roomnum].portals[i].croom].bn_info.num_nodes; k++)
{
sprintf(message, "Room %d, Node %d", Rooms[Viewer_object->roomnum].portals[i].croom, k + 1);
SendDlgItemMessage( handle, CB_ADDSTRING,0,(LPARAM) (LPCTSTR) message);
}
}
}
}
if(f_add)
{
sprintf(message, "Room %d, Node %d", Viewer_object->roomnum, 0 + 1);
SendDlgItemMessage( handle, CB_SELECTSTRING,0,(LPARAM) (LPCTSTR) message);
}
else
{
strcpy(message, "No Nodes in room");
SendDlgItemMessage( handle, CB_SELECTSTRING,0,(LPARAM) (LPCTSTR) message);
}
}
}
else if(ROOMNUM_OUTSIDE(Viewer_object->roomnum))
{
if(selection_type == EBVIEW_ROOM || selection_type == EBVIEW_ROOM_AND_NEXT_ROOMS)
{
int room = BOA_INDEX(Viewer_object->roomnum);
int tr = room - Highest_room_index - 1;
bn_list *bnlist = BNode_GetBNListPtr(Viewer_object->roomnum);
for (int i = 0; i < bnlist->num_nodes; i++)
{
f_add = true;
sprintf(message, "Region %d, Node %d", tr, i + 1);
SendDlgItemMessage( handle, CB_ADDSTRING,0,(LPARAM) (LPCTSTR) message);
}
if(selection_type == EBVIEW_ROOM_AND_NEXT_ROOMS)
{
int i;
int j;
int k;
for(i = 0; i < BOA_num_connect[tr]; i++)
{
bool f_found = false;
for(j = 0; j < num_next_rooms; j++)
{
if(next_rooms[j] == BOA_connect[tr][i].roomnum)
{
f_found = true;
break;
}
}
if(!f_found &&
BOA_connect[tr][i].roomnum >= 0 &&
!(Rooms[BOA_connect[tr][i].roomnum].flags & RF_EXTERNAL))
{
for(k = 0; k < Rooms[BOA_connect[tr][i].roomnum].bn_info.num_nodes; k++)
{
sprintf(message, "Room %d, Node %d", BOA_connect[tr][i].roomnum, k + 1);
SendDlgItemMessage( handle, CB_ADDSTRING,0,(LPARAM) (LPCTSTR) message);
}
}
}
}
if(f_add)
{
sprintf(message, "Region %d, Node %d", tr, 0 + 1);
SendDlgItemMessage( handle, CB_SELECTSTRING,0,(LPARAM) (LPCTSTR) message);
}
else
{
strcpy(message, "No Nodes in region");
SendDlgItemMessage( handle, CB_SELECTSTRING,0,(LPARAM) (LPCTSTR) message);
}
}
}
}
void CPathPadDialog::OnSetfocusAinCurrentNode()
{
ResetNodesForComboBox(IDC_AIN_CURRENT_NODE, ENode_view_type);
}
void CPathPadDialog::OnSetfocusAinOtherNode()
{
ResetNodesForComboBox(IDC_AIN_OTHER_NODE ,ENode_view_type);
}
void CPathPadDialog::OnIenavButton()
{
int node = EBNode_InsertNodeOnEdge(BNode_current_id, BNode_current_room, BNode_other_id, BNode_other_room);
if(node >= 0)
{
vector diff = Viewer_object->pos;
EBNode_Move(false, BNode_current_room, node, &diff);
World_changed = 1;
}
}
void CPathPadDialog::OnMvtnButton()
{
vector pos;
int roomnum;
bn_list *bnlist = BNode_GetBNListPtr(BNode_current_room);
if(!bnlist)
return;
pos = bnlist->nodes[BNode_current_id].pos;
if(BNode_current_room >= 0 && BNode_current_room <= Highest_room_index)
{
roomnum = BNode_current_room;
}
else
{
roomnum = GetTerrainRoomFromPos(&pos);
}
BNode_current_id,
ObjSetPos(Viewer_object, &pos, roomnum, NULL, false);
World_changed = 1;
}
void CPathPadDialog::OnAerButton()
{
bn_list *bnlist = BNode_GetBNListPtr(BNode_current_room);
if(!bnlist)
return;
for(int i = 0; i < bnlist->num_nodes; i++)
{
EBNode_AutoEdgeNode(i, BNode_current_room);
}
EBNode_VerifyGraph();
World_changed = 1;
}
void CPathPadDialog::OnOntvgpButton()
{
if (Num_game_paths<1)
{
MessageBox ("There are no paths to operate on.");
return;
}
if (Cur_object_index != -1) // we have a selected object
{
int p=D3EditState.current_path;
int n=D3EditState.current_node;
game_path *gp=&GamePaths[p];
gp->pathnodes[n].fvec = Viewer_object->orient.fvec;
gp->pathnodes[n].uvec = Viewer_object->orient.uvec;
World_changed=1;
UpdateDialog();
}
}