401 lines
9.2 KiB
C++
401 lines
9.2 KiB
C++
#include "StdAfx.h"
|
|
#include "../eterBase/CRC32.h"
|
|
#include "PythonGridSlotWindow.h"
|
|
|
|
using namespace UI;
|
|
|
|
void CGridSlotWindow::OnRenderPickingSlot()
|
|
{
|
|
if (!UI::CWindowManager::Instance().IsAttaching())
|
|
return;
|
|
|
|
BYTE byWidth, byHeight;
|
|
UI::CWindowManager::Instance().GetAttachingIconSize(&byWidth, &byHeight);
|
|
|
|
std::list<TSlot*> SlotList;
|
|
if (GetPickedSlotList(byWidth, byHeight, &SlotList))
|
|
{
|
|
DWORD dwSlotNumber = UI::CWindowManager::Instance().GetAttachingSlotNumber();
|
|
DWORD dwItemIndex = UI::CWindowManager::Instance().GetAttachingIndex();
|
|
|
|
// UseMode 이고..
|
|
if (m_isUseMode)
|
|
{
|
|
// Pick 된 아이템이 있으면..
|
|
TSlot * pSlot = *SlotList.begin();
|
|
TSlot * pCenterSlot;
|
|
if (GetSlotPointer(pSlot->dwCenterSlotNumber, &pCenterSlot))
|
|
if (pCenterSlot->isItem)
|
|
{
|
|
if (m_isUsableItem)
|
|
CPythonGraphic::Instance().SetDiffuseColor(1.0f, 1.0f, 0.0f, 0.5f);
|
|
else
|
|
CPythonGraphic::Instance().SetDiffuseColor(1.0f, 0.0f, 0.0f, 0.5f);
|
|
|
|
CPythonGraphic::Instance().RenderBar2d( m_rect.left + pCenterSlot->ixPosition,
|
|
m_rect.top + pCenterSlot->iyPosition,
|
|
m_rect.left + pCenterSlot->ixPosition + pCenterSlot->byxPlacedItemSize * ITEM_WIDTH,
|
|
m_rect.top + pCenterSlot->iyPosition + pCenterSlot->byyPlacedItemSize * ITEM_HEIGHT);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 아니면 그냥 옮기기
|
|
if (CheckMoving(dwSlotNumber, dwItemIndex, SlotList))
|
|
CPythonGraphic::Instance().SetDiffuseColor(1.0f, 1.0f, 1.0f, 0.5f);
|
|
else
|
|
CPythonGraphic::Instance().SetDiffuseColor(1.0f, 0.0f, 0.0f, 0.5f);
|
|
|
|
RECT Rect;
|
|
Rect.left = m_rect.right;
|
|
Rect.top = m_rect.bottom;
|
|
Rect.right = 0;
|
|
Rect.bottom = 0;
|
|
|
|
for (std::list<TSlot*>::iterator itor = SlotList.begin(); itor != SlotList.end(); ++itor)
|
|
{
|
|
TSlot * pSlot = *itor;
|
|
Rect.left = min(Rect.left, m_rect.left + pSlot->ixPosition);
|
|
Rect.top = min(Rect.top, m_rect.top + pSlot->iyPosition);
|
|
Rect.right = max(Rect.right, m_rect.left + pSlot->ixPosition + pSlot->byxPlacedItemSize*ITEM_WIDTH);
|
|
Rect.bottom = max(Rect.bottom, m_rect.top + pSlot->iyPosition + pSlot->byxPlacedItemSize*ITEM_HEIGHT);
|
|
}
|
|
|
|
CPythonGraphic::Instance().RenderBar2d(Rect.left, Rect.top, Rect.right, Rect.bottom);
|
|
}
|
|
}
|
|
|
|
BOOL CGridSlotWindow::GetPickedSlotPointer(TSlot ** ppSlot)
|
|
{
|
|
if (!UI::CWindowManager::Instance().IsAttaching())
|
|
return CSlotWindow::GetPickedSlotPointer(ppSlot);
|
|
|
|
BYTE byWidth, byHeight;
|
|
UI::CWindowManager::Instance().GetAttachingIconSize(&byWidth, &byHeight);
|
|
|
|
std::list<TSlot*> SlotList;
|
|
if (!GetPickedSlotList(byWidth, byHeight, &SlotList))
|
|
return FALSE;
|
|
|
|
TSlot * pMinSlot = NULL;
|
|
//DWORD dwSlotNumber = UI::CWindowManager::Instance().GetAttachingSlotNumber();
|
|
//DWORD dwAttachingItemIndex = UI::CWindowManager::Instance().GetAttachingIndex();
|
|
|
|
for (std::list<TSlot*>::iterator itor = SlotList.begin(); itor != SlotList.end(); ++itor)
|
|
{
|
|
TSlot * pSlot = *itor;
|
|
|
|
// NOTE : 한 슬롯 이상 사이즈의 아이템의 경우 가장 왼쪽 위의 슬롯 포인터를 리턴한다.
|
|
// 명시적이지 못한 코드.. 더 좋은 방법은 없는가? - [levites]
|
|
if (!pMinSlot)
|
|
{
|
|
pMinSlot = pSlot;
|
|
}
|
|
else
|
|
{
|
|
if (pSlot->dwSlotNumber < pMinSlot->dwSlotNumber)
|
|
{
|
|
pMinSlot = pSlot;
|
|
}
|
|
else
|
|
{
|
|
if (!pMinSlot->isItem && pSlot->isItem)
|
|
{
|
|
pMinSlot = pSlot;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!pMinSlot)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
TSlot * pCenterSlot;
|
|
if (!GetSlotPointer(pMinSlot->dwCenterSlotNumber, &pCenterSlot))
|
|
return FALSE;
|
|
|
|
*ppSlot = pCenterSlot;
|
|
|
|
// 현재 아이템을 들고 있는 중이고..
|
|
if (UI::CWindowManager::Instance().IsAttaching())
|
|
{
|
|
DWORD dwSlotNumber = UI::CWindowManager::Instance().GetAttachingSlotNumber();
|
|
|
|
if (dwSlotNumber == pCenterSlot->dwSlotNumber)
|
|
{
|
|
*ppSlot = pMinSlot;
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CGridSlotWindow::GetPickedSlotList(int iWidth, int iHeight, std::list<TSlot*> * pSlotPointerList)
|
|
{
|
|
long lx, ly;
|
|
GetMouseLocalPosition(lx, ly);
|
|
|
|
if (lx < 0)
|
|
return FALSE;
|
|
if (ly < 0)
|
|
return FALSE;
|
|
if (lx >= GetWidth())
|
|
return FALSE;
|
|
if (ly >= GetHeight())
|
|
return FALSE;
|
|
|
|
pSlotPointerList->clear();
|
|
|
|
int ix, iy;
|
|
if (GetPickedGridSlotPosition(lx, ly, &ix, &iy))
|
|
{
|
|
int ixHalfStep = (iWidth / 2);
|
|
//int iyHalfStep = (iHeight / 2);
|
|
|
|
int ixStart = int(ix) - int(ixHalfStep - (ixHalfStep % 2));
|
|
int ixEnd = int(ix) + int(ixHalfStep);
|
|
|
|
// FIXME : 제대로 된 계산 공식을 찾자 - [levites]
|
|
int iyStart = 0, iyEnd = 0;
|
|
|
|
if (1 == iHeight)
|
|
{
|
|
iyStart = iy;
|
|
iyEnd = iy;
|
|
}
|
|
else if (2 == iHeight)
|
|
{
|
|
iyStart = iy;
|
|
iyEnd = iy + 1;
|
|
}
|
|
else if (3 == iHeight)
|
|
{
|
|
iyStart = iy - 1;
|
|
iyEnd = iy + 1;
|
|
}
|
|
|
|
if (ixStart < 0)
|
|
{
|
|
ixEnd += -ixStart;
|
|
ixStart = 0;
|
|
}
|
|
|
|
if (iyStart < 0)
|
|
{
|
|
iyEnd += -iyStart;
|
|
iyStart = 0;
|
|
}
|
|
|
|
if (DWORD(ixEnd) >= m_dwxCount)
|
|
{
|
|
int ixTemporary = DWORD(ixEnd) - m_dwxCount + 1;
|
|
ixStart -= ixTemporary;
|
|
ixEnd -= ixTemporary;
|
|
}
|
|
|
|
if (DWORD(iyEnd) >= m_dwyCount)
|
|
{
|
|
int iyTemporary = DWORD(iyEnd) - m_dwyCount + 1;
|
|
iyStart -= iyTemporary;
|
|
iyEnd -= iyTemporary;
|
|
}
|
|
|
|
for (int i = ixStart; i <= ixEnd; ++i)
|
|
for (int j = iyStart; j <= iyEnd; ++j)
|
|
{
|
|
TSlot * pSlot;
|
|
if (GetGridSlotPointer(DWORD(i), DWORD(j), &pSlot))
|
|
{
|
|
pSlotPointerList->push_back(pSlot);
|
|
}
|
|
}
|
|
|
|
// Refine Scroll 등을 위한 예외 처리
|
|
if (m_isUseMode && 1 == pSlotPointerList->size())
|
|
{
|
|
TSlot * pMainSlot = *pSlotPointerList->begin();
|
|
|
|
std::vector<TSlot *>::iterator itor = m_SlotVector.begin();
|
|
for (; itor != m_SlotVector.end(); ++itor)
|
|
{
|
|
TSlot * pSlot = *itor;
|
|
if (pSlot->dwCenterSlotNumber == pMainSlot->dwCenterSlotNumber)
|
|
if (pSlotPointerList->end() == std::find(pSlotPointerList->begin(), pSlotPointerList->end(), pSlot))
|
|
{
|
|
pSlotPointerList->push_back(pSlot);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!pSlotPointerList->empty())
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CGridSlotWindow::GetGridSlotPointer(int ix, int iy, TSlot ** ppSlot)
|
|
{
|
|
DWORD dwSlotIndex = ix + iy*m_dwxCount;
|
|
if (dwSlotIndex >= m_SlotVector.size())
|
|
return FALSE;
|
|
|
|
*ppSlot = m_SlotVector[dwSlotIndex];
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CGridSlotWindow::GetPickedGridSlotPosition(int ixLocal, int iyLocal, int * pix, int * piy)
|
|
{
|
|
for (DWORD x = 0; x < m_dwxCount; ++x)
|
|
for (DWORD y = 0; y < m_dwyCount; ++y)
|
|
{
|
|
TSlot * pSlot;
|
|
if (!GetGridSlotPointer(x, y, &pSlot))
|
|
continue;
|
|
|
|
if (ixLocal >= pSlot->ixPosition)
|
|
if (iyLocal >= pSlot->iyPosition)
|
|
if (ixLocal <= pSlot->ixPosition + pSlot->ixCellSize)
|
|
if (iyLocal <= pSlot->iyPosition + pSlot->iyCellSize)
|
|
{
|
|
*pix = x;
|
|
*piy = y;
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void CGridSlotWindow::ArrangeGridSlot(DWORD dwStartIndex, DWORD dwxCount, DWORD dwyCount, int ixSlotSize, int iySlotSize, int ixTemporarySize, int iyTemporarySize)
|
|
{
|
|
Destroy();
|
|
|
|
m_dwxCount = dwxCount;
|
|
m_dwyCount = dwyCount;
|
|
|
|
m_SlotVector.clear();
|
|
m_SlotVector.resize(dwxCount*dwyCount);
|
|
|
|
for (DWORD x = 0; x < dwxCount; ++x)
|
|
for (DWORD y = 0; y < dwyCount; ++y)
|
|
{
|
|
DWORD dwIndex = dwStartIndex + x + y * dwxCount;
|
|
int ixPosition = x * (ixSlotSize + ixTemporarySize);
|
|
int iyPosition = y * (iySlotSize + iyTemporarySize);
|
|
|
|
AppendSlot(dwIndex, ixPosition, iyPosition, ixSlotSize, iySlotSize);
|
|
|
|
m_SlotVector[x+y*dwxCount] = &(*m_SlotList.rbegin());
|
|
}
|
|
|
|
int iWidth = dwxCount * (ixSlotSize + ixTemporarySize);
|
|
int iHeight = dwyCount * (iySlotSize + iyTemporarySize);
|
|
SetSize(iWidth, iHeight);
|
|
}
|
|
|
|
void CGridSlotWindow::OnRefreshSlot()
|
|
{
|
|
DWORD x, y;
|
|
|
|
for (x = 0; x < m_dwxCount; ++x)
|
|
for (y = 0; y < m_dwyCount; ++y)
|
|
{
|
|
TSlot * pSlot;
|
|
if (!GetGridSlotPointer(x, y, &pSlot))
|
|
continue;
|
|
|
|
pSlot->dwCenterSlotNumber = pSlot->dwSlotNumber;
|
|
}
|
|
|
|
for (x = 0; x < m_dwxCount; ++x)
|
|
for (y = 0; y < m_dwyCount; ++y)
|
|
{
|
|
TSlot * pSlot;
|
|
if (!GetGridSlotPointer(x, y, &pSlot))
|
|
continue;
|
|
|
|
if (pSlot->isItem)
|
|
{
|
|
for (DWORD xSub = 0; xSub < pSlot->byxPlacedItemSize; ++xSub)
|
|
for (DWORD ySub = 0; ySub < pSlot->byyPlacedItemSize; ++ySub)
|
|
{
|
|
TSlot * pSubSlot;
|
|
if (!GetGridSlotPointer(x+xSub, y+ySub, &pSubSlot))
|
|
continue;
|
|
|
|
pSubSlot->dwCenterSlotNumber = pSlot->dwSlotNumber;
|
|
pSubSlot->dwItemIndex = pSlot->dwItemIndex;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pSlot->dwItemIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CGridSlotWindow::CheckMoving(DWORD dwSlotNumber, DWORD dwItemIndex, const std::list<TSlot*> & c_rSlotList)
|
|
{
|
|
if (m_dwSlotStyle != SLOT_STYLE_PICK_UP)
|
|
return TRUE;
|
|
|
|
for (std::list<TSlot*>::const_iterator itor = c_rSlotList.begin(); itor != c_rSlotList.end(); ++itor)
|
|
{
|
|
TSlot * pSlot = *itor;
|
|
|
|
if (dwSlotNumber != pSlot->dwCenterSlotNumber) // 들었던 자리가 아닐 경우에
|
|
{
|
|
if (0 != pSlot->dwItemIndex || pSlot->dwCenterSlotNumber != pSlot->dwSlotNumber) // 아이템이 있고
|
|
{
|
|
if (dwItemIndex != pSlot->dwItemIndex) // 다른 아이템이면 못 옮김
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void CGridSlotWindow::Destroy()
|
|
{
|
|
CSlotWindow::Destroy();
|
|
|
|
m_SlotVector.clear();
|
|
|
|
__Initialize();
|
|
}
|
|
|
|
void CGridSlotWindow::__Initialize()
|
|
{
|
|
m_dwxCount = 0;
|
|
m_dwyCount = 0;
|
|
}
|
|
|
|
DWORD CGridSlotWindow::Type()
|
|
{
|
|
static int s_Type = GetCRC32("CGridSlotWindow", strlen("CGridSlotWindow"));
|
|
return s_Type;
|
|
}
|
|
|
|
BOOL CGridSlotWindow::OnIsType(DWORD dwType)
|
|
{
|
|
if (CGridSlotWindow::Type() == dwType)
|
|
return TRUE;
|
|
|
|
return CSlotWindow::OnIsType(dwType);
|
|
}
|
|
|
|
CGridSlotWindow::CGridSlotWindow(PyObject * ppyObject) : CSlotWindow(ppyObject)
|
|
{
|
|
}
|
|
|
|
CGridSlotWindow::~CGridSlotWindow()
|
|
{
|
|
}
|