Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
808 lines
18 KiB
C++
808 lines
18 KiB
C++
// PageTriggerContainer.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "worldcreator.h"
|
|
#include "PageTriggerContainer.h"
|
|
#include "resource.h"
|
|
|
|
#include "DlgTriggerPoint.h"
|
|
#include "DlgTriggerProperty.h"
|
|
|
|
#include "MainFrm.h"
|
|
#include "WorldCreatorView.h"
|
|
#include <BGMController.h>
|
|
#include <TriggerEvent.h>
|
|
#include <assert.h>
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
typedef unsigned char byte;
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
enum eNodeType
|
|
{
|
|
TYPE_CATEGORY = 0,
|
|
TYPE_TRIGGER = 1,
|
|
TYPE_POINTS = 2,
|
|
TYPE_POINT = 3,
|
|
TYPE_EVENTS = 4,
|
|
TYPE_EVENT = 5,
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
struct SNodeData
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
DWORD type : 4;
|
|
DWORD index1 : 14;
|
|
DWORD index2 : 14;
|
|
};
|
|
DWORD value;
|
|
};
|
|
|
|
operator DWORD() { return value; }
|
|
|
|
SNodeData();
|
|
SNodeData( eNodeType Type );
|
|
SNodeData( DWORD nodeValue );
|
|
SNodeData( int eventID, const char * szArg );
|
|
SNodeData( float x, float y, float z, long objID );
|
|
|
|
void Delete();
|
|
void GetPoint( float & x, float & y, float & z, long & objID ) const;
|
|
void GetEvent( int & eventID, char * szArg ) const;
|
|
void SetEvent( int eventID, const char * szArg );
|
|
bool operator=( const SNodeData & rhs ) const { return value == rhs.value; }
|
|
void Select() const;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
|
|
SNodeData::SNodeData()
|
|
: type( TYPE_CATEGORY )
|
|
, index1( 0 )
|
|
, index2( 0 )
|
|
{}
|
|
|
|
SNodeData::SNodeData( eNodeType Type )
|
|
: type( Type )
|
|
, index1( 0 )
|
|
, index2( 0 )
|
|
{
|
|
if( type == TYPE_TRIGGER )
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
index1 = BGMC.AddTrigger();
|
|
}
|
|
}
|
|
|
|
SNodeData::SNodeData( DWORD nodeValue )
|
|
: value( nodeValue )
|
|
{}
|
|
|
|
SNodeData::SNodeData( int eventID, const char * szArg )
|
|
: type( TYPE_EVENT )
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
index1 = BGMC.GetSelectTrigger();
|
|
index2 = BGMC.AddEvent( eventID, szArg );
|
|
}
|
|
|
|
SNodeData::SNodeData( float x, float y, float z, long objID )
|
|
: type( TYPE_POINT )
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
index1 = BGMC.GetSelectTrigger();
|
|
index2 = BGMC.AddPoint( x, y, z, objID );
|
|
}
|
|
|
|
void SNodeData::Delete()
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
|
|
switch( type )
|
|
{
|
|
case TYPE_TRIGGER :
|
|
BGMC.SelectTrigger( index1 );
|
|
BGMC.DeleteTrigger();
|
|
break;
|
|
|
|
case TYPE_CATEGORY :
|
|
case TYPE_POINTS :
|
|
case TYPE_EVENTS :
|
|
break;
|
|
|
|
case TYPE_POINT :
|
|
BGMC.SelectPoint( index1, index2 );
|
|
BGMC.DeletePoint();
|
|
break;
|
|
|
|
case TYPE_EVENT :
|
|
BGMC.SelectTrigger( index1 );
|
|
BGMC.DeleteEvent( index2 );
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SNodeData::GetPoint( float & x, float & y, float & z, long & objID ) const
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
BGMC.SelectPoint( index1, index2 );
|
|
BGMC.GetPoint( x, y, z, objID );
|
|
}
|
|
|
|
void SNodeData::GetEvent( int & eventID, char * szArg ) const
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
BGMC.SelectTrigger( index1 );
|
|
BGMC.GetEvent( index2, eventID, szArg );
|
|
}
|
|
|
|
void SNodeData::SetEvent( int eventID, const char * szArg )
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
BGMC.SelectTrigger( index1 );
|
|
BGMC.SetEvent( index2, eventID, szArg );
|
|
}
|
|
|
|
void SNodeData::Select() const
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
|
|
if( type == TYPE_TRIGGER )
|
|
{
|
|
BGMC.SelectTrigger( index1 );
|
|
}
|
|
else if( type == TYPE_POINT )
|
|
{
|
|
BGMC.SelectPoint( index1, index2 );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CPageTriggerContainer property page
|
|
|
|
IMPLEMENT_DYNCREATE(CPageTriggerContainer, CPropertyPage)
|
|
|
|
CPageTriggerContainer::CPageTriggerContainer() : CPropertyPage(CPageTriggerContainer::IDD)
|
|
{
|
|
//{{AFX_DATA_INIT(CPageTriggerContainer)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
CPageTriggerContainer::~CPageTriggerContainer()
|
|
{
|
|
}
|
|
|
|
void CPageTriggerContainer::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CPropertyPage::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CPageTriggerContainer)
|
|
DDX_Control(pDX, IDC_EDIT_EPSILON, m_editEpsilon);
|
|
DDX_Control(pDX, IDC_TREE1, m_Tree);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CPageTriggerContainer, CPropertyPage)
|
|
//{{AFX_MSG_MAP(CPageTriggerContainer)
|
|
ON_NOTIFY(NM_RCLICK, IDC_TREE1, OnRclickTree1)
|
|
ON_COMMAND(MENU_NEWTRIGGER, OnNewtrigger)
|
|
ON_COMMAND(MENU_ADDPOINT, OnAddpoint)
|
|
ON_COMMAND(MENU_ADDCATEGORY, OnAddcategory)
|
|
ON_COMMAND(MENU_TRIGGERPROPERTY, OnTriggerproperty)
|
|
ON_COMMAND(MENU_DELETENODE, OnDeletenode)
|
|
ON_NOTIFY(TVN_ENDLABELEDIT, IDC_TREE1, OnEndlabeleditTree1)
|
|
ON_COMMAND(MENU_LOADTRIGGER, OnLoadtrigger)
|
|
ON_COMMAND(MENU_SAVETRIGGER, OnSavetrigger)
|
|
ON_COMMAND(MENU_BUILDTRIGGER, OnBuildtrigger)
|
|
ON_NOTIFY(TVN_BEGINDRAG, IDC_TREE1, OnBegindragTree1)
|
|
ON_COMMAND(ID_ADDEVENT, OnAddevent)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CPageTriggerContainer message handlers
|
|
|
|
float CPageTriggerContainer::GetEpsilon()
|
|
{
|
|
char szEpsilon[1024];
|
|
m_editEpsilon.GetWindowText( szEpsilon, 1024 );
|
|
float epsilon;
|
|
epsilon = (float)strtod( szEpsilon, NULL );
|
|
|
|
return epsilon;
|
|
}
|
|
|
|
|
|
|
|
int CPageTriggerContainer::GetChildCount( HTREEITEM hItem )
|
|
{
|
|
if( hItem == NULL )
|
|
return 0;
|
|
|
|
HTREEITEM hChild = m_Tree.GetChildItem( hItem );
|
|
|
|
int i = 0;
|
|
|
|
while( hChild != NULL )
|
|
{
|
|
i++;
|
|
hChild = m_Tree.GetNextItem( hChild, TVGN_NEXT );
|
|
}
|
|
return i;
|
|
}
|
|
|
|
void CPageTriggerContainer::SetPos( HTREEITEM hItem, float x, float y, float z, long objID )
|
|
{
|
|
SNodeData nodeData = m_Tree.GetItemData( hItem );
|
|
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
|
|
if( nodeData.type == TYPE_POINT )
|
|
{
|
|
nodeData.Select();
|
|
BGMC.MovePoint( x, y, z );
|
|
BGMC.SetObjID( objID );
|
|
}
|
|
}
|
|
|
|
void CPageTriggerContainer::GetPos( HTREEITEM hItem, float & x, float & y, float & z, long & objID )
|
|
{
|
|
if( hItem == NULL )
|
|
{
|
|
x = y = z = 0.0f;
|
|
objID = 0;
|
|
}
|
|
|
|
SNodeData nodeData = m_Tree.GetItemData( hItem );
|
|
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
|
|
if( nodeData.type == TYPE_POINT )
|
|
{
|
|
nodeData.GetPoint( x, y, z, objID );
|
|
}
|
|
}
|
|
|
|
void CPageTriggerContainer::OnRclickTree1(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
CPoint point;
|
|
GetCursorPos(&point);
|
|
CMenu menu;
|
|
menu.LoadMenu(IDR_MENU_TRIGGER);
|
|
menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN,point.x,point.y,this);
|
|
|
|
*pResult = 0;
|
|
}
|
|
|
|
void CPageTriggerContainer::OnNewtrigger()
|
|
{
|
|
HTREEITEM selected = m_Tree.GetSelectedItem();
|
|
|
|
if( selected == NULL )
|
|
return;
|
|
|
|
SNodeData nodeData = m_Tree.GetItemData( selected );
|
|
|
|
//선택된 아이템이 종류 노드일 경우에만...
|
|
if( nodeData.type != TYPE_CATEGORY )
|
|
return;
|
|
|
|
HTREEITEM added = m_Tree.InsertItem( "트리거", selected );
|
|
m_Tree.Expand( selected, TVE_EXPAND );
|
|
|
|
m_Tree.SetItemData( added, SNodeData( TYPE_TRIGGER ) );
|
|
|
|
HTREEITEM vertexes = m_Tree.InsertItem( "정점", added, NULL );
|
|
m_Tree.SetItemData( vertexes, SNodeData( TYPE_POINTS ) );
|
|
|
|
HTREEITEM events = m_Tree.InsertItem( "이벤트", added, NULL );
|
|
m_Tree.SetItemData( events, SNodeData( TYPE_EVENTS ) );
|
|
|
|
HTREEITEM hItem = m_Tree.InsertItem( "점 #1", vertexes, NULL );
|
|
m_Tree.SetItemData( hItem, SNodeData( 0.0f, 0.0f, 0.0f, 0 ) );
|
|
|
|
hItem = m_Tree.InsertItem( "점 #2", vertexes, NULL );
|
|
m_Tree.SetItemData( hItem, SNodeData( 0.0f, 0.0f, 0.0f, 0 ) );
|
|
|
|
hItem = m_Tree.InsertItem( "점 #3", vertexes, NULL );
|
|
m_Tree.SetItemData( hItem, SNodeData( 0.0f, 0.0f, 0.0f, 0 ) );
|
|
|
|
hItem = m_Tree.InsertItem( "이벤트 #1", events, NULL );
|
|
m_Tree.SetItemData( hItem, SNodeData( EVENT_NONE, "" ) );
|
|
|
|
m_Tree.Expand( added, TVE_EXPAND );
|
|
}
|
|
|
|
void CPageTriggerContainer::OnAddpoint()
|
|
{
|
|
HTREEITEM selected = m_Tree.GetSelectedItem();
|
|
|
|
if( selected != NULL )
|
|
{
|
|
SNodeData nodeData = m_Tree.GetItemData( selected );
|
|
if( nodeData.type == TYPE_POINTS )
|
|
{
|
|
int ItemNum = GetChildCount( selected ) + 1;
|
|
CString itemText;
|
|
itemText.Format( "점 #%d", ItemNum );
|
|
|
|
nodeData.Select();
|
|
|
|
HTREEITEM added = m_Tree.InsertItem( itemText, selected );
|
|
m_Tree.SetItemData( added, SNodeData( 0.0f, 0.0f, 0.0f, 0 ) );
|
|
m_Tree.Expand( selected, TVE_EXPAND );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPageTriggerContainer::OnAddcategory()
|
|
{
|
|
HTREEITEM selected = m_Tree.GetSelectedItem();
|
|
|
|
if( selected != NULL )
|
|
{
|
|
SNodeData nodeData = m_Tree.GetItemData( selected );
|
|
//선택된 아이템이 종류 노드일 경우에만...
|
|
if( nodeData.type == TYPE_CATEGORY )
|
|
{
|
|
HTREEITEM added = m_Tree.InsertItem( "종류", selected );
|
|
m_Tree.SetItemData( added, SNodeData( TYPE_CATEGORY ) );
|
|
m_Tree.Expand( selected, TVE_EXPAND );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPageTriggerContainer::OnAddevent()
|
|
{
|
|
HTREEITEM selected = m_Tree.GetSelectedItem();
|
|
|
|
if( selected != NULL )
|
|
{
|
|
SNodeData nodeData = m_Tree.GetItemData( selected );
|
|
if( nodeData.type == TYPE_EVENTS )
|
|
{
|
|
int ItemNum = GetChildCount( selected ) + 1;
|
|
CString itemText;
|
|
itemText.Format( "이벤트 #%d", ItemNum );
|
|
|
|
SNodeData parentNode = m_Tree.GetItemData( m_Tree.GetParentItem( selected ) );
|
|
assert( parentNode.type == TYPE_TRIGGER );
|
|
parentNode.Select();
|
|
|
|
HTREEITEM added = m_Tree.InsertItem( itemText, selected );
|
|
m_Tree.SetItemData( added, SNodeData( EVENT_NONE, "" ) );
|
|
m_Tree.Expand( selected, TVE_EXPAND );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CPageTriggerContainer::OnDeletenode()
|
|
{
|
|
HTREEITEM selected = m_Tree.GetSelectedItem();
|
|
|
|
if( selected == NULL )
|
|
return;
|
|
|
|
SNodeData nodeData = m_Tree.GetItemData( selected );
|
|
|
|
switch( nodeData.type )
|
|
{
|
|
case TYPE_POINT :
|
|
{
|
|
if( GetChildCount( m_Tree.GetParentItem( selected ) ) <= 3 )
|
|
{
|
|
MessageBox( "트리거를 이루는 점들이 3개 이상이 되어야 하므로 주어진 노드를 지울 수 없습니다." );
|
|
return;
|
|
}
|
|
|
|
float x, y, z;
|
|
long objID;
|
|
nodeData.GetPoint( x, y, z, objID );
|
|
|
|
CMainFrame *mf=(CMainFrame*)AfxGetApp()->m_pMainWnd;
|
|
CWorldCreatorView *av=(CWorldCreatorView *)mf->GetActiveView();
|
|
av->m_SceneManager->m_MapStorage.DelMeshMap( x, y, z, objID );
|
|
|
|
m_Tree.DeleteItem( selected );
|
|
nodeData.Delete();
|
|
|
|
break;
|
|
}
|
|
case TYPE_POINTS :
|
|
case TYPE_EVENTS :
|
|
break;
|
|
|
|
case TYPE_EVENT :
|
|
|
|
m_Tree.DeleteItem( selected );
|
|
nodeData.Delete();
|
|
break;
|
|
|
|
case TYPE_TRIGGER :
|
|
{
|
|
nodeData.Select();
|
|
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
CMainFrame *mf=(CMainFrame*)AfxGetApp()->m_pMainWnd;
|
|
CWorldCreatorView *av=(CWorldCreatorView *)mf->GetActiveView();
|
|
|
|
int i = 0;
|
|
float x, y, z;
|
|
long objID;
|
|
while( BGMC.SelectPoint( nodeData.index1, i ) )
|
|
{
|
|
BGMC.GetPoint( x, y, z, objID );
|
|
av->m_SceneManager->m_MapStorage.DelMeshMap( x, y, z, objID );
|
|
i++;
|
|
}
|
|
|
|
nodeData.Delete();
|
|
m_Tree.DeleteItem( selected );
|
|
|
|
break;
|
|
}
|
|
case TYPE_CATEGORY :
|
|
|
|
if( GetChildCount( selected ) == 0 )
|
|
m_Tree.DeleteItem( selected );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
BOOL CPageTriggerContainer::OnInitDialog()
|
|
{
|
|
CPropertyPage::OnInitDialog();
|
|
|
|
HTREEITEM added = m_Tree.InsertItem( "일반 트리거" );
|
|
SNodeData nodeData( TYPE_CATEGORY );
|
|
m_Tree.SetItemData( added, nodeData );
|
|
|
|
m_editEpsilon.SetWindowText( "1000.0" );
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
void CPageTriggerContainer::OnTriggerproperty()
|
|
{
|
|
HTREEITEM selected = m_Tree.GetSelectedItem();
|
|
if( selected == NULL )
|
|
return;
|
|
|
|
SNodeData nodeData = m_Tree.GetItemData( selected );
|
|
|
|
switch( nodeData.type )
|
|
{
|
|
case TYPE_CATEGORY :
|
|
case TYPE_TRIGGER :
|
|
case TYPE_POINTS :
|
|
case TYPE_EVENTS :
|
|
break;
|
|
case TYPE_POINT :
|
|
{
|
|
CDlgTriggerPoint dlg;
|
|
long objID;
|
|
|
|
nodeData.GetPoint( dlg.m_xPos, dlg.m_yPos, dlg.m_zPos, objID );
|
|
|
|
dlg.DoModal();
|
|
break;
|
|
}
|
|
case TYPE_EVENT :
|
|
{
|
|
CDlgTriggerProperty dlg;
|
|
|
|
char szArgBuf[1024];
|
|
int eventType;
|
|
nodeData.GetEvent( eventType, szArgBuf );
|
|
|
|
dlg.m_strEventArg = szArgBuf;
|
|
dlg.SetEventType( eventType );
|
|
|
|
if( dlg.DoModal() == IDOK )
|
|
{
|
|
nodeData.SetEvent( dlg.GetEventType(), dlg.m_strEventArg );
|
|
m_Tree.SetItemData( selected, nodeData );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CPageTriggerContainer::OnEndlabeleditTree1(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
|
|
|
|
*pResult = 1;
|
|
}
|
|
|
|
void CPageTriggerContainer::OnLoadtrigger()
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
|
|
CFileDialog FileDlg( TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY
|
|
, "Trigger Files (*.Trg)|*.trg|AllFiles (*.*)|*.*||", this );
|
|
|
|
if( FileDlg.DoModal() == IDOK )
|
|
{
|
|
m_Tree.DeleteAllItems();
|
|
FILE * fp = fopen( FileDlg.GetPathName(), "rb" );
|
|
LoadAllItems( fp );
|
|
BGMC.Create( fp, true );
|
|
fclose( fp );
|
|
|
|
RenderAllObjects();
|
|
}
|
|
}
|
|
|
|
void CPageTriggerContainer::OnSavetrigger()
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
|
|
CFileDialog FileDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT
|
|
, "Trigger Files (*.trg)|*.trg|AllFiles (*.*)|*.*||", this );
|
|
|
|
if( FileDlg.DoModal() == IDOK )
|
|
{
|
|
BGMC.Rebuild( GetEpsilon() );
|
|
|
|
FILE * fp = fopen( FileDlg.GetPathName(), "wb" );
|
|
SaveAllItems( fp );
|
|
BGMC.Save( fp );
|
|
fclose( fp );
|
|
}
|
|
}
|
|
|
|
void CPageTriggerContainer::LoadItem( HTREEITEM hItem, FILE * fp )
|
|
{
|
|
if( hItem == NULL )
|
|
return;
|
|
|
|
DWORD value;
|
|
int textLen = 0;
|
|
char szBuffer[1024];
|
|
|
|
fread( &value, sizeof( DWORD ), 1, fp );
|
|
fread( &textLen, sizeof( int ), 1, fp );
|
|
fread( szBuffer, sizeof( char ), textLen, fp );
|
|
|
|
szBuffer[ textLen ] = '\0';
|
|
|
|
m_Tree.SetItemData( hItem, value );
|
|
m_Tree.SetItemText( hItem, szBuffer );
|
|
}
|
|
|
|
void CPageTriggerContainer::SaveItem( HTREEITEM hItem, FILE * fp )
|
|
{
|
|
if( hItem == NULL )
|
|
return;
|
|
|
|
SNodeData nodeData = m_Tree.GetItemData( hItem );
|
|
CString itemText = m_Tree.GetItemText( hItem );
|
|
int textLen = itemText.GetLength();
|
|
|
|
fwrite( &nodeData.value, sizeof( DWORD ), 1, fp );
|
|
fwrite( &textLen, sizeof( int ), 1, fp );
|
|
fwrite( (const char*)itemText, sizeof( char ), textLen, fp );
|
|
}
|
|
|
|
|
|
void CPageTriggerContainer::LoadAllItems( FILE * fp )
|
|
{
|
|
if( fp == NULL )
|
|
return;
|
|
|
|
typedef pair<HTREEITEM,int> QueueNode;
|
|
queue<QueueNode> ItemQueue; //아이템 핸들, 자식 개수
|
|
|
|
int nChild = 0;
|
|
|
|
//1. 루트 노드가 있는지를 읽어온다.
|
|
fread( &nChild, sizeof( int ), 1, fp );
|
|
|
|
//2. 읽어온 값이 0이면 끝낸다.
|
|
if( nChild == 0 )
|
|
return;
|
|
|
|
//3. 루트 노드를 추가하고 읽어온다.
|
|
HTREEITEM hItem = m_Tree.InsertItem( "" );
|
|
LoadItem( hItem, fp );
|
|
|
|
fread( &nChild, sizeof( int ), 1, fp );
|
|
|
|
//4. 루트 노드를 큐에 삽입한다.
|
|
ItemQueue.push( QueueNode( hItem, nChild ) );
|
|
|
|
//5. 아이템큐가 비어있지 않은 동안
|
|
while( !ItemQueue.empty() )
|
|
{
|
|
//5-1. 큐에서 하나를 빼와서 현재 노드로 세팅한다.
|
|
QueueNode node = ItemQueue.front();
|
|
ItemQueue.pop();
|
|
|
|
//5-3. 자식 개수만큼
|
|
for( int i = 0; i < node.second; i++ )
|
|
{
|
|
//5-3-1. 노드정보를 읽어와서 노드를 추가한다.
|
|
HTREEITEM hChildItem = m_Tree.InsertItem( "", node.first );
|
|
m_Tree.SetItemData( hChildItem, 0 );
|
|
LoadItem( hChildItem, fp );
|
|
|
|
//5-2. 자식 개수를 읽어온다.
|
|
fread( &nChild, sizeof( int ), 1, fp );
|
|
|
|
//5-3-2. 추가한 노드를 큐에 삽입한다.
|
|
ItemQueue.push( QueueNode( hChildItem, nChild ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPageTriggerContainer::SaveAllItems( FILE * fp )
|
|
{
|
|
if( fp == NULL )
|
|
return;
|
|
|
|
queue<HTREEITEM> ItemQueue;
|
|
|
|
//1.루트 노드를 큐에 push
|
|
HTREEITEM hItem = m_Tree.GetRootItem();
|
|
|
|
int nChild = 0;
|
|
|
|
if( hItem != NULL )
|
|
{
|
|
nChild = 1;
|
|
ItemQueue.push( hItem );
|
|
}
|
|
|
|
fwrite( &nChild, sizeof( int ), 1, fp );
|
|
|
|
//2.큐가 비어있지 않은 동안
|
|
while( !ItemQueue.empty() )
|
|
{
|
|
//2-1.큐에서 하나를 pop해와서 현재 노드에 설정
|
|
hItem = ItemQueue.front();
|
|
ItemQueue.pop();
|
|
|
|
//2-2.현재 노드를 저장
|
|
SaveItem( hItem, fp );
|
|
|
|
//2-3.현재 노드의 자식 개수를 저장
|
|
nChild = GetChildCount( hItem );
|
|
fwrite( &nChild, sizeof( int ), 1, fp );
|
|
|
|
//2-4.현재 노드의 자식 노드들을 큐에 push
|
|
HTREEITEM hChild = m_Tree.GetChildItem( hItem );
|
|
|
|
while( hChild != NULL )
|
|
{
|
|
ItemQueue.push( hChild );
|
|
hChild = m_Tree.GetNextItem( hChild, TVGN_NEXT );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPageTriggerContainer::RenderAllObjects()
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
CMainFrame *mf=(CMainFrame*)AfxGetApp()->m_pMainWnd;
|
|
CWorldCreatorView *av=(CWorldCreatorView *)mf->GetActiveView();
|
|
|
|
|
|
int nPolygon = BGMC.GetPolygonCount();
|
|
|
|
for( int i = 0; i < nPolygon; i++ )
|
|
{
|
|
int nVertex = BGMC.GetVertexCount( i );
|
|
|
|
for( int j = 0; j < nVertex; j++ )
|
|
{
|
|
float x, y, z;
|
|
|
|
BGMC.GetVertex( i, j, x, y, z );
|
|
|
|
mf->m_MeshContainerBar.m_MeshContainerSheet->m_PageObjectContainer.AddObject(vector3( x, y, z ),"Cube.R3S");
|
|
long objID=av->m_SceneManager->m_MapStorage.m_TotalObjectSceneCount-1;
|
|
BGMC.SelectPoint( i, j );
|
|
BGMC.SetObjID( objID );
|
|
|
|
CSectorScene * pSector=av->m_SceneManager->PickTerrain( x, y, z );
|
|
if( pSector )
|
|
pSector->GenerateObject();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPageTriggerContainer::OnBuildtrigger()
|
|
{
|
|
CBGMController & BGMC = CBGMController::GetInstance();
|
|
|
|
BGMC.Rebuild( GetEpsilon() );
|
|
}
|
|
|
|
void CPageTriggerContainer::OnBegindragTree1(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
|
|
|
|
HTREEITEM CurrentSelected = m_Tree.GetSelectedItem();
|
|
|
|
SNodeData nodeData = m_Tree.GetItemData( CurrentSelected );
|
|
|
|
if( nodeData.type == TYPE_POINT )
|
|
{
|
|
CMainFrame *mf=(CMainFrame*)AfxGetApp()->m_pMainWnd;
|
|
CWorldCreatorView *av=(CWorldCreatorView *)mf->GetActiveView();
|
|
av->ChangeMouseInterface(90);
|
|
}
|
|
|
|
*pResult = 0;
|
|
}
|
|
|
|
|
|
void CPageTriggerContainer::DeleteNode( unsigned index )
|
|
{
|
|
HTREEITEM item = m_Tree.GetRootItem();
|
|
SNodeData node;
|
|
node.type = TYPE_POINT;
|
|
node.index1 = ( index & 0xfffc000 ) >> 14;
|
|
node.index2 = index & 0x00003fff;
|
|
|
|
HTREEITEM finded = SearchItem( item, node );
|
|
|
|
if( finded != NULL )
|
|
{
|
|
m_Tree.DeleteItem( finded );
|
|
}
|
|
}
|
|
|
|
HTREEITEM CPageTriggerContainer::SearchItem( HTREEITEM item, DWORD nodeData )
|
|
{
|
|
item = m_Tree.GetChildItem( item );
|
|
SNodeData node = nodeData;
|
|
|
|
while( item != NULL )
|
|
{
|
|
SNodeData tempNode = m_Tree.GetItemData( item );
|
|
if( tempNode == node )
|
|
return item;
|
|
|
|
HTREEITEM hItemFinded = SearchItem( item, nodeData );
|
|
if( hItemFinded != NULL )
|
|
return hItemFinded;
|
|
|
|
item = m_Tree.GetNextItem( item, TVGN_NEXT );
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|