Files
Client/Server/ToolProject/Arrangement2/Arrangement2Dlg.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
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>
2025-11-29 20:17:20 +09:00

1686 lines
42 KiB
C++

// Arrangement2Dlg.cpp : 구현 파일
//
#include "stdafx.h"
#include "Arrangement2.h"
#include "Arrangement2Dlg.h"
#include "ijl.h"
#include "MemUtils.h"
#include "DelimitedFile.h"
#include <algorithm>
#include ".\arrangement2dlg.h"
#include <Utility/Math/Math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다.
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 대화 상자 데이터
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원
// 구현
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CArrangement2Dlg 대화 상자
CArrangement2Dlg::CArrangement2Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CArrangement2Dlg::IDD, pParent)
, m_nMapStartX(0)
, m_nMapStartZ(0)
, m_nPositionX(0)
, m_nPositionY(0)
, m_nPositionZ(0)
, m_nNumOfWorld(0)
, m_nNumOfKID(0)
, m_bVisualKID(FALSE)
, m_nProcess(0)
, m_strName(_T(""))
, m_strLevel(_T(""))
, m_strClass(_T(""))
, m_nPID(0)
, m_bVisualPID(FALSE)
, m_imageData(NULL)
, m_bmp(NULL)
, m_wRespawnArea(DEFAULT_DISTANCE)
, m_bVisualLevel(FALSE)
, m_nPartyMemNum(0)
, m_dwPageX(MAP_PAGE_X)
, m_dwPageZ(MAP_PAGE_Z)
, m_nPrevX(0)
, m_nPrevY(0)
, m_nNextX(0)
, m_nNextY(0)
, m_nGapX(0)
, m_nGapY(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CArrangement2Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_POSITIONX, m_nPositionX);
DDX_Text(pDX, IDC_POSITIONZ, m_nPositionZ);
DDX_Text(pDX, IDC_NUMINWORLD, m_nNumOfWorld);
DDX_Text(pDX, IDC_NUMOFKID, m_nNumOfKID);
DDX_Text(pDX, IDC_NAME, m_strName);
DDX_Text(pDX, IDC_LEVEL, m_strLevel);
DDX_Text(pDX, IDC_CLASS, m_strClass);
DDX_Text(pDX, IDC_RESPAWNEDIT, m_wRespawnArea);
DDX_Check(pDX, IDC_VISUALKID, m_bVisualKID);
DDX_Check(pDX, IDC_VISUALPID, m_bVisualPID);
DDX_Check(pDX, IDC_VISUALLEVEL, m_bVisualLevel);
DDX_Control(pDX, IDC_KIDCOMBO, m_ctrKIDCombo);
DDX_Control(pDX, IDC_PIDCOMBO, m_ctrPIDCombo);
DDX_Radio(pDX, IDC_ARRANGEMENT, m_nProcess);
DDV_MinMaxShort(pDX, m_wRespawnArea, 0, 30000);
DDX_Text(pDX, IDC_PARTYMEM_NUM, m_nPartyMemNum);
DDV_MinMaxInt(pDX, m_nPartyMemNum, 0, 1000000);
}
BEGIN_MESSAGE_MAP(CArrangement2Dlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_COMMAND_RANGE(ID__50, ID__800, OnZoom)
ON_UPDATE_COMMAND_UI_RANGE(ID__50, ID__800, OnUpdateZoom)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEWHEEL()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_BN_CLICKED(IDC_CREATESCRIPT, OnBnClickedCreatescript)
ON_BN_CLICKED(IDC_VISUALKID, OnBnClickedVisualkid)
ON_CBN_SELCHANGE(IDC_KIDCOMBO, OnCbnSelchangeKidcombo)
ON_BN_CLICKED(IDC_VISUALPID, OnBnClickedVisualpid)
ON_COMMAND_RANGE(ID__ZONE1, ID__ZONE16, OnZone)
ON_UPDATE_COMMAND_UI_RANGE(ID__ZONE1, ID__ZONE16, OnUpdateZone)
ON_COMMAND(ID_APP_EXIT, OnAppExit)
ON_WM_TIMER()
// ON_CBN_SELCHANGE(IDC_PIDCOMBO, OnCbnSelchangePidcombo)
ON_CBN_SELCHANGE(IDC_PIDCOMBO, OnCbnSelchangePidcombo)
ON_WM_SIZE()
END_MESSAGE_MAP()
// CArrangement2Dlg 메시지 처리기
BOOL CArrangement2Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다.
// IDM_ABOUTBOX는 시스템 명령 범위에 있어야 합니다.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// ===============================================================================
// Version History
// -------------------------------------------------------------------------------
//
// - 1.12
// + 16번존의 석상 ID 를 그대로 두기위해 "석상 ID 유지하기" 체크박스 추가
//
// - 1.11
// + 사용하지 않는 UI 삭제 (스카우트, 이동패턴) 및 수정
// + 존 16번 로드시 8번존 이미지가 나오던 버그 수정
//
// - 1.10
// + 존 16번(다크 카나번) 추가
//
// - 1.09
// + 이미 사용한 PID의 경우 몇 마리가 그룹에 묶여있는지 표시해주는 기능 추가
//
// - 1.08
// + PID 설정후 그룹(파티)이 설정되지 않던 버그 수정
//
// - 1.07
// + PID 콤보박스 수정
//
// - 1.06
// + 몬스터 스크립트에 LOD 여부 추가
//
// - 1.05
// + 몬스터를 배치, 삭제가 자주 있어서 중복된 CID의 몬스터가 생기던 버그 수정
// + (스크립트를 생성할때 CID를 부여하는 식으로 변경되었음)
//
// - 1.04
// + 몬스터 리스트의 레벨이 경험점의 수치로 표시되던 버그 수정
//
// - 1.03
// + 통합존 (12번) 추가
//
// - 1.02
// + 1.01 버젼의 CID 가 중복으로 생성되던 버그 수정
//
// - 1.01
// + Monster CID 넘버링 수정 (KID 별로 넘버링되어서 CID를 만들어낸다.)
// + 한 종류의 몬스터는 2047 마리까지 배치 가능하다.
//
// - 1.00
// + 버전 넘버링 시작
// + 치프 몬스터 추가에 더불어 배포
//
// ===============================================================================
SetWindowText("Arrangement Tool - Ver. 1.12");
// 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
// 프레임워크가 이 작업을 자동으로 수행합니다.
SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다.
SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다.
CMenu menu;
menu.LoadMenu(IDR_MENU1);
SetMenu(&menu);
menu.Detach();
m_nSelectedZoom = ID__100;
m_fMagnification = 1;
m_nTimer = SetTimer(1, 1000, 0);
m_bBlink = false;
m_bDragObject = false;
m_bDragScreen = false;
ZeroMemory(&m_bmi, sizeof(BITMAPINFO));
m_bmp = NULL;
char strTemp[ID_LENGTH];
for (int i = 0; i < MAX_NUM; ++i)
{
sprintf(strTemp, "%d", i);
m_ctrPIDCombo.InsertString(i, strTemp);
m_ctrPIDCombo.SetItemData(i, i);
}
ClearBitmap();
return TRUE; // 컨트롤에 대한 포커스를 설정하지 않을 경우 TRUE를 반환합니다.
}
void CArrangement2Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면
// 아래 코드가 필요합니다. 문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는
// 프레임워크에서 이 작업을 자동으로 수행합니다.
class CDrawMonster
{
public:
CDrawMonster(Graphics& graphics, Pen& pen, const int nWidth, const int nHeight)
: m_graphics(graphics), m_pen(pen), m_nWidth(nWidth), m_nHeight(nHeight) { }
~CDrawMonster() { }
void DrawEllipse(SolidBrush& brush, int nX, int nY)
{
m_graphics.DrawEllipse(&m_pen, nX, nY, m_nWidth, m_nHeight);
m_graphics.FillEllipse(&brush, nX, nY, m_nWidth, m_nHeight);
}
void DrawRectangle(SolidBrush& brush, int nX, int nY)
{
m_graphics.DrawRectangle(&m_pen, nX, nY, m_nWidth, m_nHeight);
m_graphics.FillRectangle(&brush, nX, nY, m_nWidth, m_nHeight);
}
void DrawRespawnArea(SolidBrush& brush, int nLeft, int nTop, int nRight, int nBottom)
{
m_graphics.DrawEllipse(&m_pen, nLeft, nTop, nRight - nLeft, nBottom - nTop);
m_graphics.FillEllipse(&brush, nLeft, nTop, nRight - nLeft, nBottom - nTop);
}
private:
Graphics& m_graphics;
Pen& m_pen;
const int m_nWidth;
const int m_nHeight;
};
void CArrangement2Dlg::OnPaint()
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트
if (IsIconic())
{
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 아이콘을 그립니다.
dc.DrawIcon(x, y, m_hIcon);
}
else
{
HDC hdcCompatible = CreateCompatibleDC(dc.m_hDC);
HBITMAP hbmScreen = CreateCompatibleBitmap(dc.m_hDC,
GetDeviceCaps(dc.m_hDC, HORZRES),
GetDeviceCaps(dc.m_hDC, VERTRES));
SelectObject(hdcCompatible, hbmScreen);
StretchDIBits(hdcCompatible,
0, 0, m_dwPageX, m_dwPageZ,
m_nMapStartX, (int)(m_imageDims.cy-m_dwPageZ / m_fMagnification-m_nMapStartZ),
(int)(m_dwPageX / m_fMagnification), (int)(m_dwPageZ / m_fMagnification),
m_bmp, &m_bmi, DIB_RGB_COLORS, SRCCOPY);
Graphics graphics(hdcCompatible);
Pen hBlackPen(Color(255, 0, 0, 0));
SolidBrush hRedBrush(Color(255, 255, 0, 0));
SolidBrush hGreenBrush(Color(255, 0, 255, 0));
SolidBrush hBlueBrush(Color(255, 0, 0, 255));
SolidBrush hWhiteBrush(Color(255, 255, 255, 255));
SolidBrush hYellowBrush(Color(255, 255, 255, 0));
SolidBrush hGrayBrush(Color(127, 128, 128, 128));
SolidBrush hBlackBrush(Color(255, 0, 0, 0));
FontFamily fontFamily(L"굴림");
Font font(&fontFamily, 11, FontStyleRegular, UnitPixel);
CDrawMonster draw(graphics, hBlackPen, 4, 4);
wchar_t szID[ID_LENGTH];
MonsterList::iterator begin = m_lstMonster.begin();
MonsterList::iterator end = m_lstMonster.end();
for (;begin != end; ++begin)
{
Monster* lpMonster = *begin;
int nPosInScreenX = (int)((lpMonster->m_nPosX - m_nMapStartX - SECTOR_SIZE) * m_fMagnification);
int nPosInScreenZ = (int)((lpMonster->m_nPosZ + m_nMapStartZ - m_imageDims.cy + SECTOR_SIZE) * m_fMagnification * (-1));
if (0 <= nPosInScreenX && nPosInScreenX <= m_dwPageX - 4 &&
0 <= nPosInScreenZ && nPosInScreenZ <= m_dwPageZ)
{
SolidBrush* lpSolidBrush = NULL;
switch (lpMonster->m_nMovingPattern)
{
case PATTERN_AREA: lpSolidBrush = &hRedBrush; break;
case PATTERN_FIX: lpSolidBrush = &hGreenBrush; break;
case PATTERN_ROUTE: lpSolidBrush = &hBlueBrush; break;
case PATTERN_NONAREA: lpSolidBrush = &hWhiteBrush; break;
}
if (0 != lpMonster->m_wRespawnArea && lpMonster->m_wRespawnArea != DEFAULT_DISTANCE)
{
int nLeft = (int)((lpMonster->m_nPosX - m_nMapStartX - SECTOR_SIZE - lpMonster->m_wRespawnArea) * m_fMagnification);
int nTop = (int)((lpMonster->m_nPosZ + m_nMapStartZ - m_imageDims.cy + SECTOR_SIZE - lpMonster->m_wRespawnArea) * m_fMagnification * (-1));
int nRight = (int)((lpMonster->m_nPosX - m_nMapStartX - SECTOR_SIZE + lpMonster->m_wRespawnArea) * m_fMagnification);
int nBottom = (int)((lpMonster->m_nPosZ + m_nMapStartZ - m_imageDims.cy + SECTOR_SIZE + lpMonster->m_wRespawnArea) * m_fMagnification * (-1));
draw.DrawRespawnArea(hGrayBrush, nLeft, nTop, nRight, nBottom);
}
if (true == m_bBlink && lpMonster->m_nPID == m_nPID && 0 != m_nPID)
{
lpSolidBrush = &hYellowBrush;
}
nPosInScreenX -= 2;
nPosInScreenZ -= 2;
if (NULL != lpSolidBrush && lpMonster->m_bScout)
{
draw.DrawEllipse(*lpSolidBrush, nPosInScreenX, nPosInScreenZ);
}
else
{
draw.DrawRectangle(*lpSolidBrush, nPosInScreenX, nPosInScreenZ);
}
if (nPosInScreenX <= m_dwPageX - 20)
{
if (m_bVisualKID)
{
PointF pointF((REAL)nPosInScreenX, (REAL)nPosInScreenZ + 2);
_snwprintf(szID, ID_LENGTH, L"K %d", lpMonster->m_nKID);
DrawOutLineText(graphics, font, pointF, szID);
}
if (m_bVisualLevel)
{
PointF pointF((REAL)nPosInScreenX, (REAL)nPosInScreenZ + 12);
_snwprintf(szID, ID_LENGTH, L"L %d", lpMonster->m_nLevel);
DrawOutLineText(graphics, font, pointF, szID);
}
if (m_bVisualPID && 0 != lpMonster->m_nPID)
{
PointF pointF((REAL)nPosInScreenX, (REAL)nPosInScreenZ + 22);
_snwprintf(szID, ID_LENGTH, L"P %d", lpMonster->m_nPID);
DrawOutLineText(graphics, font, pointF, szID);
}
}
}
}
BitBlt(dc.m_hDC, 0, 0, m_dwPageX, m_dwPageZ, hdcCompatible, 0, 0, SRCCOPY);
DeleteObject(hbmScreen);
DeleteDC(hdcCompatible);
m_nNumOfWorld = (int)(m_lstMonster.size());
UpdateData(FALSE);
CDialog::OnPaint();
}
}
void CArrangement2Dlg::DrawOutLineText(Graphics& graphics, Font& font, PointF pointF, wchar_t* strText)
{
SolidBrush hWhiteBrush(Color(255, 255, 255, 255));
SolidBrush hBlackBrush(Color(255, 0, 0, 0));
++pointF.X;
++pointF.Y;
graphics.DrawString(strText, static_cast<int>(wcslen(strText)), &font, pointF, &hBlackBrush);
pointF.X -= 2;
graphics.DrawString(strText, static_cast<int>(wcslen(strText)), &font, pointF, &hBlackBrush);
pointF.Y -= 2;
graphics.DrawString(strText, static_cast<int>(wcslen(strText)), &font, pointF, &hBlackBrush);
pointF.X += 2;
graphics.DrawString(strText, static_cast<int>(wcslen(strText)), &font, pointF, &hBlackBrush);
--pointF.X;
++pointF.Y;
graphics.DrawString(strText, static_cast<int>(wcslen(strText)), &font, pointF, &hWhiteBrush);
}
// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서
// 이 함수를 호출합니다.
HCURSOR CArrangement2Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
BOOL CArrangement2Dlg::DestroyWindow()
{
ClearData();
KillTimer(m_nTimer);
return CDialog::DestroyWindow();
}
void CArrangement2Dlg::ClearData()
{
SAFE_DELETE_ARRAY(m_imageData);
SAFE_DELETE_ARRAY(m_bmp);
std::for_each(m_lstMonster.begin(), m_lstMonster.end(), MemUtils::fnDelete());
m_lstMonster.clear();
m_lstMonsterInfo.clear();
m_mapStatueID.clear() ;
}
void CArrangement2Dlg::OnTimer(UINT nIDEvent)
{
UpdateData(TRUE);
m_bBlink = !m_bBlink;
Invalidate(FALSE);
CDialog::OnTimer(nIDEvent);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 스크롤 바
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CArrangement2Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
switch (nSBCode)
{
case SB_LEFT:
m_nMapStartX = 0;
break;
case SB_RIGHT:
m_nMapStartX = (int)(m_imageDims.cx-m_dwPageX/m_fMagnification);
break;
case SB_ENDSCROLL:
break;
case SB_LINELEFT:
m_nMapStartX--;
if (m_nMapStartX<0) { m_nMapStartX = 0; }
break;
case SB_LINERIGHT:
m_nMapStartX++;
break;
case SB_PAGELEFT:
m_nMapStartX -= (int)(m_dwPageX/m_fMagnification);
if (m_nMapStartX<0) { m_nMapStartX = 0; }
break;
case SB_PAGERIGHT:
m_nMapStartX += (int)(m_dwPageX/m_fMagnification);
if (m_nMapStartX>(int)(m_imageDims.cx-m_dwPageX/m_fMagnification))
m_nMapStartX = (int)(m_imageDims.cx-m_dwPageX/m_fMagnification);;
break;
case SB_THUMBPOSITION:
m_nMapStartX = nPos;
break;
case SB_THUMBTRACK:
m_nMapStartX = nPos;
break;
}
SetScrollPos(SB_HORZ, m_nMapStartX);
Invalidate(FALSE);
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CArrangement2Dlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
switch (nSBCode)
{
case SB_TOP:
m_nMapStartZ = 0;
break;
case SB_BOTTOM:
m_nMapStartZ = (int)(m_imageDims.cy-m_dwPageZ/m_fMagnification);
break;
case SB_ENDSCROLL:
break;
case SB_LINEDOWN:
m_nMapStartZ++;
break;
case SB_LINEUP:
m_nMapStartZ--;
if (m_nMapStartZ<0) { m_nMapStartZ = 0; }
break;
case SB_PAGEDOWN:
m_nMapStartZ += (int)(m_dwPageZ/m_fMagnification);
if (m_nMapStartZ>(int)(m_imageDims.cy-m_dwPageZ/m_fMagnification))
m_nMapStartZ = (int)(m_imageDims.cy-m_dwPageZ/m_fMagnification);
break;
case SB_PAGEUP:
m_nMapStartZ -= (int)(m_dwPageZ/m_fMagnification);
if (m_nMapStartZ<0) { m_nMapStartZ = 0; }
break;
case SB_THUMBPOSITION:
m_nMapStartZ = nPos;
break;
case SB_THUMBTRACK:
m_nMapStartZ = nPos;
break;
}
SetScrollPos(SB_VERT, m_nMapStartZ);
Invalidate(FALSE);
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 이미지 로딩 하기전에 m_bmp 를 검은색 화면으로 지워주는 함수
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CArrangement2Dlg::ClearBitmap()
{
m_imageChannels = 3;
m_imageDims.cx = m_dwPageX;
m_imageDims.cy = m_dwPageZ;
int imageSize = m_dwPageX * m_imageChannels * m_dwPageZ;
m_bmp = new BYTE[ imageSize ];
::ZeroMemory(m_bmp, sizeof(imageSize));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 이미지 로딩
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CArrangement2Dlg::OpenJPGFile(LPCTSTR lpszPathName)
{
JPEG_CORE_PROPERTIES image;
ZeroMemory( &image, sizeof( JPEG_CORE_PROPERTIES ) );
BYTE* imageData;
BeginWaitCursor();
TRY
if ( ijlInit( &image ) != IJL_OK )
{
TRACE( "Cannot initialize Intel JPEG library\n" );
AfxThrowUserException();
}
image.JPGFile = const_cast<char*>(lpszPathName);
if ( ijlRead( &image, IJL_JFILE_READPARAMS ) != IJL_OK )
{
TRACE( "Cannot read JPEG file header from %s file\n",
image.JPGFile );
AfxThrowUserException();
}
// Set the JPG color space ... this will always be
// somewhat of an educated guess at best because JPEG
// is "color blind" (i.e., nothing in the bit stream
// tells you what color space the data was encoded from).
// However, in this example we assume that we are
// reading JFIF files which means that 3 channel images
// are in the YCbCr color space and 1 channel images are
// in the Y color space.
switch(image.JPGChannels)
{
case 1:
image.JPGColor = IJL_G;
image.DIBChannels = 3;
image.DIBColor = IJL_BGR;
break;
case 3:
image.JPGColor = IJL_YCBCR;
image.DIBChannels = 3;
image.DIBColor = IJL_BGR;
break;
case 4:
image.JPGColor = IJL_YCBCRA_FPX;
image.DIBChannels = 4;
image.DIBColor = IJL_RGBA_FPX;
break;
default:
// This catches everything else, but no
// color twist will be performed by the IJL.
image.DIBColor = (IJL_COLOR)IJL_OTHER;
image.JPGColor = (IJL_COLOR)IJL_OTHER;
image.DIBChannels = image.JPGChannels;
break;
}
image.DIBWidth = image.JPGWidth;
image.DIBHeight = image.JPGHeight;
image.DIBPadBytes = IJL_DIB_PAD_BYTES(image.DIBWidth,image.DIBChannels);
int imageSize = (image.DIBWidth * image.DIBChannels + image.DIBPadBytes) *
image.DIBHeight;
imageData = new BYTE[ imageSize ];
if ( imageData == NULL )
{
TRACE( "Cannot allocate memory for image\n" );
AfxThrowUserException();
}
image.DIBBytes = imageData;
if ( ijlRead( &image, IJL_JFILE_READWHOLEIMAGE ) != IJL_OK )
{
TRACE( "Cannot read image data from %s file\n", image.JPGFile );
delete[] imageData;
AfxThrowUserException();
}
if ( ijlFree( &image ) != IJL_OK )
{
TRACE( "Cannot free Intel(R) JPEG library" );
}
if (image.DIBColor == IJL_RGBA_FPX)
{
RGBA_FPX_to_BGRA(imageData,image.DIBWidth,image.DIBHeight);
}
CATCH_ALL( e )
EndWaitCursor();
ijlFree( &image );
AfxMessageBox( "Error opening JPEG file" );
return FALSE;
END_CATCH_ALL
// 이미 로드되어 있었다면 메모리를 해제시켜준다.
SAFE_DELETE_ARRAY(m_imageData);
SAFE_DELETE_ARRAY(m_bmp);
// initializing incapsulated image with correct values
m_imageData = imageData;
m_imageDims.cx = image.DIBWidth;
m_imageDims.cy = image.DIBHeight;
m_imageChannels = image.DIBChannels;
EndWaitCursor();
// now we have
// m_imageData containing image data, and
// m_imageDims with image dimensions, and
// m_imageChannels with image number of channels
return TRUE;
}
void CArrangement2Dlg::RGBA_FPX_to_BGRA(BYTE* data,int width,int height)
{
int i;
int j;
int pad;
int line_width;
BYTE r, g, b, a;
BYTE* ptr;
ptr = data;
pad = IJL_DIB_PAD_BYTES(width,4);
line_width = width * 4 + pad;
for(i = 0; i < height; i++)
{
ptr = data + line_width*i;
for(j = 0; j < width; j++)
{
r = ptr[0];
g = ptr[1];
b = ptr[2];
a = ptr[3];
ptr[2] = (BYTE)( (r*a+1) >> 8 );
ptr[1] = (BYTE)( (g*a+1) >> 8 );
ptr[0] = (BYTE)( (b*a+1) >> 8 );
ptr += 4;
}
}
return;
}
void CArrangement2Dlg::InitialUpdate()
{
BITMAPINFOHEADER& bih = m_bmi.bmiHeader;
::ZeroMemory( &bih, sizeof( BITMAPINFOHEADER ) );
bih.biSize = sizeof( BITMAPINFOHEADER );
bih.biWidth = m_imageDims.cx;
bih.biHeight = -m_imageDims.cy;
bih.biCompression = BI_RGB;
bih.biPlanes = 1;
switch(m_imageChannels)
{
case 3:
bih.biBitCount = 24;
break;
case 4:
bih.biBitCount = 32;
break;
default:
TRACE("Unsupported number of channels!\n");
break;
}
if ( m_bmp != NULL )
delete[] m_bmp;
int pad = IJL_DIB_PAD_BYTES(m_imageDims.cx,m_imageChannels);
int imageSize = (m_imageDims.cx * m_imageChannels + pad) * m_imageDims.cy;
m_bmp = new BYTE[ imageSize ];
if ( m_bmp == NULL )
return;
::ZeroMemory(m_bmp,imageSize);
::CopyMemory(m_bmp,m_imageData,imageSize);
return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 존 로딩
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CArrangement2Dlg::OnZone(UINT nID)
{
m_nLoadedZone = nID;
ClearData();
switch (m_nLoadedZone)
{
case ID__ZONE1:
OpenJPGFile("Zone01.jpg");
break;
case ID__ZONE2:
OpenJPGFile("Zone02.jpg");
break;
case ID__ZONE3:
OpenJPGFile("Zone03.jpg");
break;
case ID__ZONE4:
OpenJPGFile("Zone04.jpg");
break;
case ID__ZONE5:
OpenJPGFile("Zone05.jpg");
break;
case ID__ZONE8:
OpenJPGFile("Zone08.jpg");
break;
case ID__ZONE9:
OpenJPGFile("Zone09.jpg");
break;
case ID__ZONE12:
OpenJPGFile("Zone12.jpg");
break;
case ID__ZONE16:
OpenJPGFile("Zone16.jpg");
break;
case ID__ZONE100:
// OpenJPGFile("Zone100.jpg");
return;
break;
}
InitialUpdate();
LoadScript();
SetScrollRange(SB_HORZ, 0, m_imageDims.cx - m_dwPageX);
SetScrollRange(SB_VERT, 0, m_imageDims.cy - m_dwPageZ);
Invalidate(FALSE);
}
void CArrangement2Dlg::OnUpdateZone(CCmdUI *pCmdUI)
{
pCmdUI->SetCheck(m_nLoadedZone == pCmdUI->m_nID);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 줌
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CArrangement2Dlg::OnZoom(UINT nID)
{
m_nSelectedZoom = nID;
switch (m_nSelectedZoom)
{
case ID__50:
m_fMagnification = 0.5;
break;
case ID__100:
m_fMagnification = 1;
break;
case ID__200:
m_fMagnification = 2;
break;
case ID__400:
m_fMagnification = 4;
break;
case ID__800:
m_fMagnification = 8;
break;
}
SetScrollRange(SB_HORZ, 0, (int)(m_imageDims.cx-m_dwPageX/m_fMagnification));
SetScrollRange(SB_VERT, 0, (int)(m_imageDims.cy-m_dwPageZ/m_fMagnification));
Invalidate(FALSE);
}
void CArrangement2Dlg::OnUpdateZoom(CCmdUI *pCmdUI)
{
pCmdUI->SetCheck(m_nSelectedZoom == pCmdUI->m_nID);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 마우스 인터페이스
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CArrangement2Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bDragScreen)
{
m_nMapStartX += DragScreenStartPoint.x - point.x;
m_nMapStartZ += DragScreenStartPoint.y - point.y;
if (m_nMapStartX < 0)
m_nMapStartX = 0;
if (m_nMapStartX > (int)(m_imageDims.cx-m_dwPageX / m_fMagnification))
m_nMapStartX = (int)(m_imageDims.cx-m_dwPageX / m_fMagnification);
if (m_nMapStartZ < 0)
m_nMapStartZ = 0;
if (m_nMapStartZ > (int)(m_imageDims.cy-m_dwPageZ / m_fMagnification))
m_nMapStartZ = (int)(m_imageDims.cy-m_dwPageZ / m_fMagnification);
SetScrollPos(SB_HORZ, m_nMapStartX);
SetScrollPos(SB_VERT, m_nMapStartZ);
Invalidate(FALSE);
DragScreenStartPoint = point;
}
else
{
UpdateData(TRUE);
m_nPositionX = m_nMapStartX + (int)(point.x / m_fMagnification) + SECTOR_SIZE;
m_nPositionY = 0;
m_nPositionZ = m_imageDims.cy - (int)(m_nMapStartZ + point.y / m_fMagnification) - SECTOR_SIZE;
if (point.x >= 0 && point.x <= m_dwPageX && point.y >= 0 && point.y <= m_dwPageZ)
{
if (m_bDragObject)
{
m_lstMonster[m_DragObjectIndex]->m_nPosX = m_nPositionX;
m_lstMonster[m_DragObjectIndex]->m_nPosZ = m_nPositionZ;
Invalidate(FALSE);
}
UpdateData(FALSE);
}
}
CDialog::OnMouseMove(nFlags, point);
}
void CArrangement2Dlg::OnLButtonDown(UINT nFlags, CPoint point)
{
int nPosInScreenX, nPosInScreenZ;
switch (m_nProcess)
{
case ARRANGEMENT:
{
for (int i = 0; i < (int)(m_lstMonster.size()); i++)
{
nPosInScreenX = (int)((m_lstMonster[i]->m_nPosX - m_nMapStartX - SECTOR_SIZE) * m_fMagnification);
nPosInScreenZ = (int)((m_lstMonster[i]->m_nPosZ + m_nMapStartZ - m_imageDims.cy + SECTOR_SIZE) * m_fMagnification * (-1));
if (nPosInScreenX - 3 <= point.x && point.x < nPosInScreenX + 3 &&
nPosInScreenZ - 3 <= point.y && point.y < nPosInScreenZ + 3)
{
m_bDragObject = true;
m_DragObjectIndex = i;
break;
}
}
} break;
case ERASE:
case PARTY:
{
if (0 <= point.x && point.x < m_dwPageX && 0 <= point.y && point.y < m_dwPageZ)
{
CRectTracker tracker;
if (tracker.TrackRubberBand(this, point, TRUE))
{
tracker.m_rect.NormalizeRect();
long temp;
if (tracker.m_rect.left > tracker.m_rect.right)
{
temp = tracker.m_rect.left;
tracker.m_rect.left = tracker.m_rect.right;
tracker.m_rect.right = temp;
}
if (tracker.m_rect.top > tracker.m_rect.bottom)
{
temp = tracker.m_rect.top;
tracker.m_rect.top = tracker.m_rect.bottom;
tracker.m_rect.bottom = temp;
}
for (int i = 0; i < (int)(m_lstMonster.size()); i++)
{
nPosInScreenX = (int)((m_lstMonster[i]->m_nPosX - m_nMapStartX - SECTOR_SIZE) * m_fMagnification);
nPosInScreenZ = (int)((m_lstMonster[i]->m_nPosZ + m_nMapStartZ - m_imageDims.cy + SECTOR_SIZE) * m_fMagnification * (-1));
if (tracker.m_rect.left <= nPosInScreenX && nPosInScreenX < tracker.m_rect.right &&
tracker.m_rect.top <= nPosInScreenZ && nPosInScreenZ < tracker.m_rect.bottom)
{
if (ERASE == m_nProcess)
{
m_lstMonster.erase(m_lstMonster.begin() + i);
i--;
}
else
{
m_lstMonster[i]->m_nPID = m_nPID;
}
}
}
CalculateNumOfPID();
if (MAX_PARTY_MEMBER_NUM < m_nPartyMemNum)
{
AfxMessageBox("파티원의 인원이 최대수치 10을 넘어 갔습니다.");
}
UpdateData(FALSE);
Invalidate(FALSE);
}
}
} break;
}
CDialog::OnLButtonDown(nFlags, point);
}
void CArrangement2Dlg::OnLButtonUp(UINT nFlags, CPoint point)
{
UpdateData(TRUE);
int nKID = static_cast<int>(m_ctrKIDCombo.GetItemData(m_ctrKIDCombo.GetCurSel()));
if (m_lstMonsterInfo.end() == m_lstMonsterInfo.find(nKID))
{
if (m_bDragObject)
{
m_bDragObject = false;
}
CDialog::OnLButtonUp(nFlags, point);
return;
}
if (0 <= point.x && point.x < m_dwPageX && 0 <= point.y && point.y < m_dwPageZ)
{
if (false == m_bDragObject)
{
if (0xFFFF == m_nNumOfKID)
{
AfxMessageBox("한 종류의 몬스터를 최대로 배치했습니다.\n더이상 이 몬스터를 배치할수 없습니다.");
}
else
{
Monster* tempMonster = new Monster;
tempMonster->m_dwCID = 0;
tempMonster->m_bScout = false;
tempMonster->m_nKID = nKID;
tempMonster->m_nMovingPattern = 0;
tempMonster->m_wRespawnArea = m_wRespawnArea;
tempMonster->m_nPosX = m_nPositionX;
tempMonster->m_nPosY = m_nPositionY;
tempMonster->m_nPosZ = m_nPositionZ;
MonsterInfoList::iterator itr = m_lstMonsterInfo.find(nKID);
if (itr != m_lstMonsterInfo.end())
{
tempMonster->m_nLevel = atoi( (itr->second).m_strLevel );
}
m_lstMonster.push_back(tempMonster);
m_nNumOfKID++;
}
}
else
{
m_bDragObject = false;
}
Invalidate(FALSE);
UpdateData(FALSE);
}
CDialog::OnLButtonUp(nFlags, point);
}
BOOL CArrangement2Dlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
m_nMapStartZ += (int)(m_dwPageZ/m_fMagnification/(-240/zDelta));
if (m_nMapStartZ<0)
m_nMapStartZ = 0;
if (m_nMapStartZ>(int)(m_imageDims.cy-m_dwPageZ/m_fMagnification))
m_nMapStartZ = (int)(m_imageDims.cy-m_dwPageZ/m_fMagnification);
SetScrollPos(SB_VERT, m_nMapStartZ);
Invalidate(FALSE);
return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}
void CArrangement2Dlg::OnRButtonDown(UINT nFlags, CPoint point)
{
m_bDragScreen = true;
DragScreenStartPoint = point;
CDialog::OnRButtonDown(nFlags, point);
}
void CArrangement2Dlg::OnRButtonUp(UINT nFlags, CPoint point)
{
m_bDragScreen = false;
CDialog::OnRButtonUp(nFlags, point);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 스크립트
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CArrangement2Dlg::OnBnClickedCreatescript()
{
char ArrangementFileName[MAX_PATH] = ".\\Arrangement";
switch (m_nLoadedZone)
{
case ID__ZONE1: strcat(ArrangementFileName, "1.txt"); break;
case ID__ZONE2: strcat(ArrangementFileName, "2.txt"); break;
case ID__ZONE3: strcat(ArrangementFileName, "3.txt"); break;
case ID__ZONE4: strcat(ArrangementFileName, "4.txt"); break;
case ID__ZONE5: strcat(ArrangementFileName, "5.txt"); break;
case ID__ZONE8: strcat(ArrangementFileName, "8.txt"); break;
case ID__ZONE9: strcat(ArrangementFileName, "9.txt"); break;
case ID__ZONE12: strcat(ArrangementFileName, "12.txt"); break;
case ID__ZONE16: strcat(ArrangementFileName, "16.txt"); break;
case ID__ZONE100: strcat(ArrangementFileName, "100.txt"); break;
default:
::AfxMessageBox("Arrangement Script 파일 이름을 설정할\n존 ID가 잘못되었습니다.");
return;
}
FILE *fp;
if (NULL == (fp = fopen(ArrangementFileName, "wt")))
{
::AfxMessageBox("스크립트 작성에 실패하였습니다.");
return;
}
fprintf(fp, "CID KID PID X Y Z Scout MovingPattern RespawnArea\n");
typedef std::map<unsigned long, unsigned short> NumOfKIDMap;
NumOfKIDMap lstNumOfKID;
for (int i = 0; i < (int)(m_lstMonster.size()); ++i)
{
lstNumOfKID.insert(std::make_pair(m_lstMonster[i]->m_nKID, 0));
}
unsigned short nNumOfKID = 0;
for (int i = 0; i < (int)(m_lstMonster.size()); i++)
{
unsigned long pid = 0;
if (0 != m_lstMonster[i]->m_nPID)
{
pid = (MONSTER_PARTY_BIT | m_lstMonster[i]->m_nPID);
}
// CID 생성
if ( IsStatue(m_lstMonster[i]->m_nKID) )
{
StatueIDMap::iterator itr = m_mapStatueID.find( sStatueKey(m_lstMonster[i]->m_nPosX, m_lstMonster[i]->m_nPosZ) ) ;
if ( itr != m_mapStatueID.end() )
{
m_lstMonster[i]->m_dwCID = itr->second ;
}
}
else
{
NumOfKIDMap::iterator itr = lstNumOfKID.find(m_lstMonster[i]->m_nKID);
if (itr != lstNumOfKID.end())
{
nNumOfKID = lstNumOfKID[m_lstMonster[i]->m_nKID];
++lstNumOfKID[m_lstMonster[i]->m_nKID];
}
else
{
lstNumOfKID.insert(std::make_pair(m_lstMonster[i]->m_nKID, 0));
nNumOfKID = 0;
}
m_lstMonster[i]->m_dwCID = MONSTER_BIT + m_lstMonster[i]->m_nKID + (nNumOfKID << 16);
}
fprintf(fp, "0x%08x\t%d\t0x%08x\t%d\t%d\t%d\t%d\t%d\t%d\n",
m_lstMonster[i]->m_dwCID, m_lstMonster[i]->m_nKID, pid,
m_lstMonster[i]->m_nPosX, m_lstMonster[i]->m_nPosY, m_lstMonster[i]->m_nPosZ,
m_lstMonster[i]->m_bScout, m_lstMonster[i]->m_nMovingPattern, m_lstMonster[i]->m_wRespawnArea);
Sleep(0);
}
lstNumOfKID.clear();
fclose(fp);
::AfxMessageBox("스크립트 작성이 완료되었습니다.");
}
void CArrangement2Dlg::LoadScript(void)
{
char MonsterProtoTypeFileName[MAX_PATH] = ".\\MonsterProtoType.txt";
char ArrangementFileName[MAX_PATH] = ".\\Arrangement";
switch (m_nLoadedZone)
{
case ID__ZONE1: strcat(ArrangementFileName, "1.txt"); break;
case ID__ZONE2: strcat(ArrangementFileName, "2.txt"); break;
case ID__ZONE3: strcat(ArrangementFileName, "3.txt"); break;
case ID__ZONE4: strcat(ArrangementFileName, "4.txt"); break;
case ID__ZONE5: strcat(ArrangementFileName, "5.txt"); break;
case ID__ZONE8: strcat(ArrangementFileName, "8.txt"); break;
case ID__ZONE9: strcat(ArrangementFileName, "9.txt"); break;
case ID__ZONE12: strcat(ArrangementFileName, "12.txt"); break;
case ID__ZONE16: strcat(ArrangementFileName, "16.txt"); break;
case ID__ZONE100: strcat(ArrangementFileName, "100.txt"); break;
default:
::AfxMessageBox("Arrangement Script 파일 이름을 설정할\n존 ID가 잘못되었습니다.");
return;
}
CDelimitedFile DelimitedFile;
// 몬스터 프로토 타입 파일을 읽어들인다.
if (DelimitedFile.Open(MonsterProtoTypeFileName) == FALSE)
{
::AfxMessageBox("MonsterProtoType.txt 파일이 없습니다.");
return;
}
int nWasteBasket = 0;
MonsterInfo tempMonsterInfo;
while (DelimitedFile.ReadLine())
{
memset(&tempMonsterInfo, 0, sizeof(MonsterInfo));
DelimitedFile.ReadData(tempMonsterInfo.m_nKID);
DelimitedFile.ReadString((LPSTR)(LPCTSTR)tempMonsterInfo.m_strName, MAX_STRING_LENGTH);
DelimitedFile.ReadData(nWasteBasket); // 형태 플래그
DelimitedFile.ReadData(nWasteBasket); // LOD 여부
DelimitedFile.ReadData(nWasteBasket); // Nation
DelimitedFile.ReadString((LPSTR)(LPCTSTR)tempMonsterInfo.m_strClass, MAX_STRING_LENGTH);
for (int i=0; i<14; i++)
{
DelimitedFile.ReadData(nWasteBasket);
}
DelimitedFile.ReadString((LPSTR)(LPCTSTR)tempMonsterInfo.m_strLevel, MAX_STRING_LENGTH);
m_lstMonsterInfo[tempMonsterInfo.m_nKID] = tempMonsterInfo;
}
DelimitedFile.Close();
std::vector<int> kidList;
kidList.reserve(m_lstMonsterInfo.size());
MonsterInfoList::iterator pos_monlist = m_lstMonsterInfo.begin();
MonsterInfoList::iterator end_monlist = m_lstMonsterInfo.end();
for(;pos_monlist != end_monlist; ++pos_monlist)
{
kidList.push_back(pos_monlist->first);
}
char szKID[MAX_PATH];
std::sort(kidList.begin(), kidList.end(), std::less<int>());
std::vector<int>::const_iterator pos = kidList.begin();
std::vector<int>::const_iterator end = kidList.end();
for(;pos != end; ++pos)
{
int nKID = *pos;
int nInsertIndex = m_ctrKIDCombo.GetCount();
_snprintf(szKID, MAX_PATH - 1, "%d(%s)",
nKID, m_lstMonsterInfo[nKID].m_strName);
szKID[MAX_PATH - 1] = 0;
m_ctrKIDCombo.InsertString(nInsertIndex, szKID);
m_ctrKIDCombo.SetItemData(nInsertIndex, nKID);
}
// Arrangement 파일을 읽어들인다.
if (DelimitedFile.Open(ArrangementFileName, 1) == FALSE)
{
return;
}
int nOldKID = 0xFFFF;
while (DelimitedFile.ReadLine())
{
Monster* tempMonster = new Monster;
char strTemp[MAX_PATH];
DelimitedFile.ReadString(strTemp, MAX_PATH); // CID
unsigned long dwCID = Math::Convert::Atoi(strTemp);
DelimitedFile.ReadData(tempMonster->m_nKID); // KID
if (nOldKID != tempMonster->m_nKID)
{
CalculateNumOfKID(tempMonster->m_nKID);
nOldKID = tempMonster->m_nKID;
}
tempMonster->m_dwCID = 0;
DelimitedFile.ReadString(strTemp, MAX_PATH);
tempMonster->m_nPID = static_cast<int>(Math::Convert::Atoi(strTemp) & ~MONSTER_PARTY_BIT);
DelimitedFile.ReadData(tempMonster->m_nPosX);
DelimitedFile.ReadData(tempMonster->m_nPosY);
DelimitedFile.ReadData(tempMonster->m_nPosZ);
DelimitedFile.ReadData(tempMonster->m_bScout);
DelimitedFile.ReadData(tempMonster->m_nMovingPattern);
DelimitedFile.ReadData(tempMonster->m_wRespawnArea);
MonsterInfoList::iterator itr = m_lstMonsterInfo.find(tempMonster->m_nKID);
if (itr != m_lstMonsterInfo.end())
{
tempMonster->m_nLevel = atoi( (itr->second).m_strLevel );
}
m_lstMonster.push_back(tempMonster);
++m_nNumOfKID;
// 석상이라면...
if (IsStatue(tempMonster->m_nKID))
{
m_mapStatueID.insert( std::make_pair( sStatueKey(tempMonster->m_nPosX, tempMonster->m_nPosZ), dwCID ) ).second ;
}
}
DelimitedFile.Close();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 정보 표시
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CArrangement2Dlg::OnBnClickedVisualkid()
{
UpdateData(TRUE);
Invalidate(FALSE);
}
void CArrangement2Dlg::OnBnClickedVisualpid()
{
UpdateData(TRUE);
Invalidate(FALSE);
}
void CArrangement2Dlg::OnCbnSelchangeKidcombo()
{
UpdateData(TRUE);
// 이 종류의 몬스터 개체수.
int nKID = static_cast<int>(m_ctrKIDCombo.GetItemData(m_ctrKIDCombo.GetCurSel()));
CalculateNumOfKID(nKID);
UpdateData(FALSE);
}
void CArrangement2Dlg::OnCbnSelchangePidcombo()
{
UpdateData(TRUE);
// 선택된 PID 설정
m_nPID = static_cast<int>(m_ctrPIDCombo.GetItemData(m_ctrPIDCombo.GetCurSel()));
CalculateNumOfPID();
UpdateData(FALSE);
}
void CArrangement2Dlg::CalculateNumOfKID(int nKID)
{
m_nNumOfKID = 0;
MonsterInfoList::iterator pos_moninfo = m_lstMonsterInfo.find(nKID);
MonsterInfoList::iterator end_moninfo = m_lstMonsterInfo.end();
if(pos_moninfo != end_moninfo)
{
const MonsterInfo& monsterInfo = pos_moninfo->second;
m_strName = monsterInfo.m_strName;
m_strLevel = monsterInfo.m_strLevel;
m_strClass = monsterInfo.m_strClass;
MonsterList::const_iterator pos_mon = m_lstMonster.begin();
MonsterList::const_iterator end_mon = m_lstMonster.end();
for(; pos_mon != end_mon; ++pos_mon)
{
if(nKID == (*pos_mon)->m_nKID)
{
++m_nNumOfKID;
}
}
}
else
{
m_strName = m_strLevel = m_strClass = "NULL";
}
}
void CArrangement2Dlg::CalculateNumOfPID()
{
m_nPartyMemNum = 0;
MonsterList::const_iterator pos_mon = m_lstMonster.begin();
MonsterList::const_iterator end_mon = m_lstMonster.end();
for(; pos_mon != end_mon; ++pos_mon)
{
if (m_nPID == (*pos_mon)->m_nPID && m_nPID != 0)
{
++m_nPartyMemNum;
}
}
}
void CArrangement2Dlg::OnAppExit()
{
// TODO: 여기에 명령 처리기 코드를 추가합니다.
int ret = ::AfxMessageBox("정말로 종료하시겠습니까?", MB_YESNO);
if (ret == IDYES)
{
DestroyWindow();
}
}
BOOL CArrangement2Dlg::IsStatue(unsigned short wKID) CONST
{
if (wKID >= MIN_STATUE_KID && wKID <= MAX_STATUE_KID)
{
return TRUE ;
}
return FALSE ;
}
void CArrangement2Dlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
/*m_nNextX = cx;
m_nNextY = cy;
if(0 != m_nPrevX || 0 != m_nPrevY)
{
m_nGapX = m_nNextX - m_nPrevX;
m_nGapY = m_nNextY - m_nPrevY;
}
m_dwPageX = cx - 300;
m_dwPageZ = cy;
CDialog *pDialog;
this->GetWindowRect(&m_rectWindow);
CButton* pButton = NULL;
CStatic* pStatic = NULL;
CEdit* pEdit = NULL;
CComboBox* pComboBox = NULL;
CCheckListBox* pCheckBox = NULL;
pButton = static_cast<CButton*> (GetDlgItem(IDC_CREATESCRIPT));
SetObjectPos(pButton);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATIC1));
SetObjectPos(pStatic);
pButton = static_cast<CButton*> (GetDlgItem(IDC_ARRANGEMENT));
SetObjectPos(pButton);
pButton = static_cast<CButton*> (GetDlgItem(IDC_ERASE));
SetObjectPos(pButton);
pButton = static_cast<CButton*> (GetDlgItem(IDC_GROUP));
SetObjectPos(pButton);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATIC2));
SetObjectPos(pStatic);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATICKID));
SetObjectPos(pStatic);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATICNAME));
SetObjectPos(pStatic);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATICLEVEL));
SetObjectPos(pStatic);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATICCLASS));
SetObjectPos(pStatic);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATICOBJNUM));
SetObjectPos(pStatic);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATICRESPAWN));
SetObjectPos(pStatic);
pComboBox = static_cast<CComboBox*> (GetDlgItem(IDC_KIDCOMBO));
SetObjectPos(pComboBox);
pEdit = static_cast<CEdit*> (GetDlgItem(IDC_NAME));
SetObjectPos(pEdit);
pEdit = static_cast<CEdit*> (GetDlgItem(IDC_LEVEL));
SetObjectPos(pEdit);
pEdit = static_cast<CEdit*> (GetDlgItem(IDC_CLASS));
SetObjectPos(pEdit);
pEdit = static_cast<CEdit*> (GetDlgItem(IDC_NUMOFKID));
SetObjectPos(pEdit);
pEdit = static_cast<CEdit*> (GetDlgItem(IDC_RESPAWNEDIT));
SetObjectPos(pEdit);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATIC3));
SetObjectPos(pStatic);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATICPID));
SetObjectPos(pStatic);
pComboBox = static_cast<CComboBox*> (GetDlgItem(IDC_PIDCOMBO));
SetObjectPos(pComboBox);
pEdit = static_cast<CEdit*> (GetDlgItem(IDC_PARTYMEM_NUM));
SetObjectPos(pEdit);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATIC4));
SetObjectPos(pStatic);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATIC5));
SetObjectPos(pStatic);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATICX));
SetObjectPos(pStatic);
pEdit = static_cast<CEdit*> (GetDlgItem(IDC_POSITIONX));
SetObjectPos(pEdit);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATICZ));
SetObjectPos(pStatic);
pEdit = static_cast<CEdit*> (GetDlgItem(IDC_POSITIONZ));
SetObjectPos(pEdit);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATICMONTNUM));
SetObjectPos(pStatic);
pEdit = static_cast<CEdit*> (GetDlgItem(IDC_NUMINWORLD));
SetObjectPos(pEdit);
pStatic = static_cast<CStatic*> (GetDlgItem(IDC_STATIC6));
SetObjectPos(pStatic);
pCheckBox = static_cast<CCheckListBox*> (GetDlgItem(IDC_STATICMONTNUM));
SetObjectPos(pCheckBox);
pCheckBox = static_cast<CCheckListBox*> (GetDlgItem(IDC_VISUALKID));
SetObjectPos(pCheckBox);
pCheckBox = static_cast<CCheckListBox*> (GetDlgItem(IDC_VISUALLEVEL));
SetObjectPos(pCheckBox);
pCheckBox = static_cast<CCheckListBox*> (GetDlgItem(IDC_VISUALPID));
SetObjectPos(pCheckBox);
m_nPrevX = m_nNextX;
m_nPrevY = m_nNextY;
Invalidate();*/
}
template <class T>
void CArrangement2Dlg::SetObjectPos(T* pObject)
{
RECT rectObject;
if(NULL != pObject)
{
pObject->GetWindowRect(&rectObject);
pObject->SetWindowPos(NULL,
rectObject.left, rectObject.top,
0, 0, SWP_NOSIZE|SW_SHOW);
}
}