Port route 4-c: NPC shop (PythonShop.cpp) + app cursor state
- UserInterface/PythonShop.cpp ported verbatim (shop module, initshop after initfly); pending stub and module stubs removed. - 40250 PythonApplicationCursor.cpp and SetMouseHandler moved into the platform CPythonApplication on file-static members; GetCursorNum out of line, since uishop's app.GetCursor() dereferenced the missing application object. - Fake server: general store (npclist 9003) answers CG_ON_CLICK with GC_SHOP START, CG_SHOP BUY/SELL2/END like CShop::Buy / CShopManager::Sell. - port.login_flow step 10: click the shopkeeper, right-click buy, drag-sell, ESC close. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
85e176bdd5
commit
a12e7fea42
@@ -92,14 +92,6 @@ void AddStubConstants_safebox(PyObject* poModule)
|
||||
}
|
||||
|
||||
// 40250 UserInterface/PythonShop.cpp
|
||||
void AddStubConstants_shop(PyObject* poModule)
|
||||
{
|
||||
(void) poModule;
|
||||
PyModule_AddIntConstant(poModule, "SHOP_SLOT_COUNT", SHOP_HOST_ITEM_MAX_NUM);
|
||||
PyModule_AddIntConstant(poModule, "SHOP_COIN_TYPE_GOLD", SHOP_COIN_TYPE_GOLD);
|
||||
PyModule_AddIntConstant(poModule, "SHOP_COIN_TYPE_SECONDARY_COIN", SHOP_COIN_TYPE_SECONDARY_COIN);
|
||||
}
|
||||
|
||||
// 40250 UserInterface/PythonSkill.cpp
|
||||
// 40250 UserInterface/PythonSoundManagerModule.cpp
|
||||
void AddStubConstants_snd(PyObject* poModule)
|
||||
|
||||
@@ -12,7 +12,6 @@ void AddStubConstants_messenger(PyObject* poModule);
|
||||
void AddStubConstants_profiler(PyObject* poModule);
|
||||
void AddStubConstants_quest(PyObject* poModule);
|
||||
void AddStubConstants_safebox(PyObject* poModule);
|
||||
void AddStubConstants_shop(PyObject* poModule);
|
||||
void AddStubConstants_snd(PyObject* poModule);
|
||||
void AddStubConstants_systemSetting(PyObject* poModule);
|
||||
void AddStubConstants_udp(PyObject* poModule);
|
||||
@@ -217,46 +216,6 @@ PyMethodDef methods_safebox[] = {
|
||||
{ "GetMallSize", stub_safebox_GetMallSize, METH_VARARGS },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
// 40250 UserInterface/PythonShop.cpp: shop export names.
|
||||
PyObject* stub_shop_Open(PyObject*, PyObject*) { return stub_call_named("shop.Open", Py_BuildNone()); }
|
||||
PyObject* stub_shop_Close(PyObject*, PyObject*) { return stub_call_named("shop.Close", Py_BuildNone()); }
|
||||
PyObject* stub_shop_IsOpen(PyObject*, PyObject*) { return stub_call_named("shop.IsOpen", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_shop_IsPrivateShop(PyObject*, PyObject*) { return stub_call_named("shop.IsPrivateShop", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_shop_IsMainPlayerPrivateShop(PyObject*, PyObject*) { return stub_call_named("shop.IsMainPlayerPrivateShop", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_shop_GetItemID(PyObject*, PyObject*) { return stub_call_named("shop.GetItemID", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_shop_GetItemCount(PyObject*, PyObject*) { return stub_call_named("shop.GetItemCount", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_shop_GetItemPrice(PyObject*, PyObject*) { return stub_call_named("shop.GetItemPrice", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_shop_GetItemMetinSocket(PyObject*, PyObject*) { return stub_call_named("shop.GetItemMetinSocket", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_shop_GetItemAttribute(PyObject*, PyObject*) { return stub_call_named("shop.GetItemAttribute", Py_BuildValue("ii", 0, 0)); }
|
||||
PyObject* stub_shop_GetTabCount(PyObject*, PyObject*) { return stub_call_named("shop.GetTabCount", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_shop_GetTabName(PyObject*, PyObject*) { return stub_call_named("shop.GetTabName", Py_BuildValue("s", "")); }
|
||||
PyObject* stub_shop_GetTabCoinType(PyObject*, PyObject*) { return stub_call_named("shop.GetTabCoinType", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_shop_ClearPrivateShopStock(PyObject*, PyObject*) { return stub_call_named("shop.ClearPrivateShopStock", Py_BuildNone()); }
|
||||
PyObject* stub_shop_AddPrivateShopItemStock(PyObject*, PyObject*) { return stub_call_named("shop.AddPrivateShopItemStock", Py_BuildNone()); }
|
||||
PyObject* stub_shop_DelPrivateShopItemStock(PyObject*, PyObject*) { return stub_call_named("shop.DelPrivateShopItemStock", Py_BuildNone()); }
|
||||
PyObject* stub_shop_GetPrivateShopItemPrice(PyObject*, PyObject*) { return stub_call_named("shop.GetPrivateShopItemPrice", Py_BuildValue("i", 0)); }
|
||||
PyObject* stub_shop_BuildPrivateShop(PyObject*, PyObject*) { return stub_call_named("shop.BuildPrivateShop", Py_BuildNone()); }
|
||||
PyMethodDef methods_shop[] = {
|
||||
{ "Open", stub_shop_Open, METH_VARARGS },
|
||||
{ "Close", stub_shop_Close, METH_VARARGS },
|
||||
{ "IsOpen", stub_shop_IsOpen, METH_VARARGS },
|
||||
{ "IsPrivateShop", stub_shop_IsPrivateShop, METH_VARARGS },
|
||||
{ "IsMainPlayerPrivateShop", stub_shop_IsMainPlayerPrivateShop, METH_VARARGS },
|
||||
{ "GetItemID", stub_shop_GetItemID, METH_VARARGS },
|
||||
{ "GetItemCount", stub_shop_GetItemCount, METH_VARARGS },
|
||||
{ "GetItemPrice", stub_shop_GetItemPrice, METH_VARARGS },
|
||||
{ "GetItemMetinSocket", stub_shop_GetItemMetinSocket, METH_VARARGS },
|
||||
{ "GetItemAttribute", stub_shop_GetItemAttribute, METH_VARARGS },
|
||||
{ "GetTabCount", stub_shop_GetTabCount, METH_VARARGS },
|
||||
{ "GetTabName", stub_shop_GetTabName, METH_VARARGS },
|
||||
{ "GetTabCoinType", stub_shop_GetTabCoinType, METH_VARARGS },
|
||||
{ "ClearPrivateShopStock", stub_shop_ClearPrivateShopStock, METH_VARARGS },
|
||||
{ "AddPrivateShopItemStock", stub_shop_AddPrivateShopItemStock, METH_VARARGS },
|
||||
{ "DelPrivateShopItemStock", stub_shop_DelPrivateShopItemStock, METH_VARARGS },
|
||||
{ "GetPrivateShopItemPrice", stub_shop_GetPrivateShopItemPrice, METH_VARARGS },
|
||||
{ "BuildPrivateShop", stub_shop_BuildPrivateShop, METH_VARARGS },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
// 40250 UserInterface/PythonSoundManagerModule.cpp: snd export names.
|
||||
PyObject* stub_snd_PlaySound(PyObject*, PyObject*) { return stub_call_named("snd.PlaySound", Py_BuildNone()); }
|
||||
PyObject* stub_snd_PlaySound3D(PyObject*, PyObject*) { return stub_call_named("snd.PlaySound3D", Py_BuildNone()); }
|
||||
@@ -420,11 +379,6 @@ void init_2v0_gameplay_stubs() {
|
||||
PyModule_AddIntConstant(module, "__port_stub__", 1);
|
||||
AddStubConstants_safebox(module);
|
||||
}
|
||||
{
|
||||
PyObject* module = Py_InitModule("shop", methods_shop);
|
||||
PyModule_AddIntConstant(module, "__port_stub__", 1);
|
||||
AddStubConstants_shop(module);
|
||||
}
|
||||
{
|
||||
PyObject* module = Py_InitModule("snd", methods_snd);
|
||||
PyModule_AddIntConstant(module, "__port_stub__", 1);
|
||||
|
||||
@@ -402,6 +402,7 @@ bool run_main_script_body(const char* lpCmdLine, std::string* error)
|
||||
initMiniMap();
|
||||
initeffect();
|
||||
initfly();
|
||||
initshop();
|
||||
initskill();
|
||||
initBackground();
|
||||
initServerStateChecker();
|
||||
|
||||
@@ -301,15 +301,113 @@ void CPythonApplication::OnUIRender()
|
||||
UI::CWindowManager& rkUIMgr=UI::CWindowManager::Instance();
|
||||
rkUIMgr.Render();
|
||||
}
|
||||
BOOL CPythonApplication::SetCursorNum(int) { MT_PLATFORM_STUB(); return FALSE; }
|
||||
void CPythonApplication::SetCursorVisible(BOOL, bool) { MT_PLATFORM_STUB(); }
|
||||
BOOL CPythonApplication::GetCursorVisible() { MT_PLATFORM_STUB(); return FALSE; }
|
||||
bool CPythonApplication::GetLiarCursorOn() { MT_PLATFORM_STUB(); return false; }
|
||||
void CPythonApplication::SetCursorMode(int) { MT_PLATFORM_STUB(); }
|
||||
// 40250 returns m_iCursorMode, CURSOR_MODE_HARDWARE from the constructor until SetCursorMode (PythonApplicationCursor.cpp:92).
|
||||
// PORT: SetCursorMode is still a stub, so the mode stays the constructor's.
|
||||
int CPythonApplication::GetCursorMode() { return CURSOR_MODE_HARDWARE; }
|
||||
void CPythonApplication::SetMouseHandler(PyObject*) { MT_PLATFORM_STUB(); }
|
||||
// 40250 PythonApplicationCursor.cpp. PORT: the members live here until the application object exists
|
||||
// (initial values from the constructor and CreateCursors); the host draws no hardware cursor, so every
|
||||
// shape in [0, CURSOR_COUNT) counts as loaded in place of m_CursorHandleMap.
|
||||
namespace
|
||||
{
|
||||
int s_iCursorNum = CPythonApplication::CURSOR_SHAPE_NORMAL; // m_iCursorNum
|
||||
int s_iContinuousCursorNum = CPythonApplication::CURSOR_SHAPE_NORMAL; // m_iContinuousCursorNum
|
||||
BOOL s_bCursorVisible = TRUE; // m_bCursorVisible
|
||||
bool s_bLiarCursorOn = false; // m_bLiarCursorOn
|
||||
int s_iCursorMode = CPythonApplication::CURSOR_MODE_HARDWARE; // m_iCursorMode
|
||||
PyObject* s_poMouseHandler = NULL; // m_poMouseHandler
|
||||
}
|
||||
|
||||
void CPythonApplication::SetCursorVisible(BOOL bFlag, bool bLiarCursorOn)
|
||||
{
|
||||
s_bCursorVisible = bFlag;
|
||||
s_bLiarCursorOn = bLiarCursorOn;
|
||||
// PORT: 40250 also counts ShowCursor up or down in hardware mode; the host has no OS cursor to hide.
|
||||
}
|
||||
|
||||
BOOL CPythonApplication::GetCursorVisible()
|
||||
{
|
||||
return s_bCursorVisible;
|
||||
}
|
||||
|
||||
bool CPythonApplication::GetLiarCursorOn()
|
||||
{
|
||||
return s_bLiarCursorOn;
|
||||
}
|
||||
|
||||
int CPythonApplication::GetCursorMode()
|
||||
{
|
||||
return s_iCursorMode;
|
||||
}
|
||||
|
||||
int CPythonApplication::GetCursorNum()
|
||||
{
|
||||
return s_iCursorNum;
|
||||
}
|
||||
|
||||
BOOL CPythonApplication::__IsContinuousChangeTypeCursor(int iCursorNum)
|
||||
{
|
||||
switch (iCursorNum)
|
||||
{
|
||||
case CURSOR_SHAPE_NORMAL:
|
||||
case CURSOR_SHAPE_ATTACK:
|
||||
case CURSOR_SHAPE_TARGET:
|
||||
case CURSOR_SHAPE_MAGIC:
|
||||
case CURSOR_SHAPE_BUY:
|
||||
case CURSOR_SHAPE_SELL:
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CPythonApplication::SetCursorNum(int iCursorNum)
|
||||
{
|
||||
if (CURSOR_SHAPE_NORMAL == iCursorNum)
|
||||
{
|
||||
if (!__IsContinuousChangeTypeCursor(s_iCursorNum))
|
||||
{
|
||||
iCursorNum = s_iContinuousCursorNum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__IsContinuousChangeTypeCursor(s_iCursorNum))
|
||||
{
|
||||
s_iContinuousCursorNum = s_iCursorNum;
|
||||
}
|
||||
}
|
||||
|
||||
if (CURSOR_MODE_HARDWARE == s_iCursorMode)
|
||||
{
|
||||
// PORT: m_CursorHandleMap.find(iCursorNum) and SetCursor(hCursor).
|
||||
if (iCursorNum < 0 || iCursorNum >= CURSOR_COUNT)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s_iCursorNum = iCursorNum;
|
||||
|
||||
PyCallClassMemberFunc(s_poMouseHandler, "ChangeCursor", Py_BuildValue("(i)", s_iCursorNum));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CPythonApplication::SetCursorMode(int iMode)
|
||||
{
|
||||
switch (iMode)
|
||||
{
|
||||
case CURSOR_MODE_HARDWARE:
|
||||
s_iCursorMode = CURSOR_MODE_HARDWARE;
|
||||
break;
|
||||
|
||||
case CURSOR_MODE_SOFTWARE:
|
||||
s_iCursorMode = CURSOR_MODE_SOFTWARE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 40250 PythonApplication.cpp:871.
|
||||
void CPythonApplication::SetMouseHandler(PyObject* poMouseHandler)
|
||||
{
|
||||
s_poMouseHandler = poMouseHandler;
|
||||
}
|
||||
void CPythonApplication::SetGlobalCenterPosition(LONG, LONG) { MT_PLATFORM_STUB(); }
|
||||
void CPythonApplication::SetFPS(int) { MT_PLATFORM_STUB(); }
|
||||
time_t CPythonApplication::GetServerTime() { MT_PLATFORM_STUB(); return 0; }
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
// Stand-in for the 40250 logic unit UserInterface/PythonShop.cpp, not ported yet: the members the ported units
|
||||
// reference, as platform_stub.py stubs. Delete this file in the commit that ports the unit into port/
|
||||
// (docs/PORT-PLAN.md).
|
||||
#include "UserInterface/StdAfx.h"
|
||||
#include "UserInterface/PythonShop.h"
|
||||
|
||||
#include "../../PlatformStub.h"
|
||||
|
||||
CPythonShop::CPythonShop()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
CPythonShop::~CPythonShop()
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonShop::Clear() -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonShop::SetItemData(DWORD, const TShopItemData &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonShop::SetItemData(BYTE, DWORD, const TShopItemData &) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonShop::SetTabCoinType(BYTE, BYTE) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonShop::SetTabName(BYTE, const char *) -> void
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
}
|
||||
|
||||
auto CPythonShop::IsOpen() -> BOOL
|
||||
{
|
||||
MT_PLATFORM_STUB();
|
||||
return mt_platform_stub_return<BOOL>();
|
||||
}
|
||||
@@ -179,7 +179,8 @@ class CPythonApplication final : public CMSApplication, public CInputKeyboard, p
|
||||
bool GetLiarCursorOn();
|
||||
void SetCursorMode(int iMode);
|
||||
int GetCursorMode();
|
||||
int GetCursorNum() { return m_iCursorNum; }
|
||||
// PORT: out of line (platform/UserInterface/PythonApplication.cpp) while there is no application object.
|
||||
int GetCursorNum();
|
||||
|
||||
void SetMouseHandler(PyObject * poMouseHandler);
|
||||
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
#include "StdAfx.h"
|
||||
#include "PythonShop.h"
|
||||
|
||||
#include "PythonNetworkStream.h"
|
||||
|
||||
//BOOL CPythonShop::GetSlotItemID(DWORD dwSlotPos, DWORD* pdwItemID)
|
||||
//{
|
||||
// if (!CheckSlotIndex(dwSlotPos))
|
||||
// return FALSE;
|
||||
// const TShopItemData * itemData;
|
||||
// if (!GetItemData(dwSlotPos, &itemData))
|
||||
// return FALSE;
|
||||
// *pdwItemID=itemData->vnum;
|
||||
// return TRUE;
|
||||
//}
|
||||
void CPythonShop::SetTabCoinType(BYTE tabIdx, BYTE coinType)
|
||||
{
|
||||
if (tabIdx >= m_bTabCount)
|
||||
{
|
||||
TraceError("Out of Index. tabIdx(%d) must be less than %d.", tabIdx, SHOP_TAB_COUNT_MAX);
|
||||
return;
|
||||
}
|
||||
m_aShoptabs[tabIdx].coinType = coinType;
|
||||
}
|
||||
|
||||
BYTE CPythonShop::GetTabCoinType(BYTE tabIdx)
|
||||
{
|
||||
if (tabIdx >= m_bTabCount)
|
||||
{
|
||||
TraceError("Out of Index. tabIdx(%d) must be less than %d.", tabIdx, SHOP_TAB_COUNT_MAX);
|
||||
return 0xff;
|
||||
}
|
||||
return m_aShoptabs[tabIdx].coinType;
|
||||
}
|
||||
|
||||
void CPythonShop::SetTabName(BYTE tabIdx, const char* name)
|
||||
{
|
||||
if (tabIdx >= m_bTabCount)
|
||||
{
|
||||
TraceError("Out of Index. tabIdx(%d) must be less than %d.", tabIdx, SHOP_TAB_COUNT_MAX);
|
||||
return;
|
||||
}
|
||||
m_aShoptabs[tabIdx].name = name;
|
||||
}
|
||||
|
||||
const char* CPythonShop::GetTabName(BYTE tabIdx)
|
||||
{
|
||||
if (tabIdx >= m_bTabCount)
|
||||
{
|
||||
TraceError("Out of Index. tabIdx(%d) must be less than %d.", tabIdx, SHOP_TAB_COUNT_MAX);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m_aShoptabs[tabIdx].name.c_str();
|
||||
}
|
||||
|
||||
void CPythonShop::SetItemData(DWORD dwIndex, const TShopItemData & c_rShopItemData)
|
||||
{
|
||||
BYTE tabIdx = dwIndex / SHOP_HOST_ITEM_MAX_NUM;
|
||||
DWORD dwSlotPos = dwIndex % SHOP_HOST_ITEM_MAX_NUM;
|
||||
|
||||
SetItemData(tabIdx, dwSlotPos, c_rShopItemData);
|
||||
}
|
||||
|
||||
BOOL CPythonShop::GetItemData(DWORD dwIndex, const TShopItemData ** c_ppItemData)
|
||||
{
|
||||
BYTE tabIdx = dwIndex / SHOP_HOST_ITEM_MAX_NUM;
|
||||
DWORD dwSlotPos = dwIndex % SHOP_HOST_ITEM_MAX_NUM;
|
||||
|
||||
return GetItemData(tabIdx, dwSlotPos, c_ppItemData);
|
||||
}
|
||||
|
||||
void CPythonShop::SetItemData(BYTE tabIdx, DWORD dwSlotPos, const TShopItemData & c_rShopItemData)
|
||||
{
|
||||
if (tabIdx >= SHOP_TAB_COUNT_MAX || dwSlotPos >= SHOP_HOST_ITEM_MAX_NUM)
|
||||
{
|
||||
TraceError("Out of Index. tabIdx(%d) must be less than %d. dwSlotPos(%d) must be less than %d", tabIdx, SHOP_TAB_COUNT_MAX, dwSlotPos, SHOP_HOST_ITEM_MAX_NUM);
|
||||
return;
|
||||
}
|
||||
|
||||
m_aShoptabs[tabIdx].items[dwSlotPos] = c_rShopItemData;
|
||||
}
|
||||
|
||||
BOOL CPythonShop::GetItemData(BYTE tabIdx, DWORD dwSlotPos, const TShopItemData ** c_ppItemData)
|
||||
{
|
||||
if (tabIdx >= SHOP_TAB_COUNT_MAX || dwSlotPos >= SHOP_HOST_ITEM_MAX_NUM)
|
||||
{
|
||||
TraceError("Out of Index. tabIdx(%d) must be less than %d. dwSlotPos(%d) must be less than %d", tabIdx, SHOP_TAB_COUNT_MAX, dwSlotPos, SHOP_HOST_ITEM_MAX_NUM);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*c_ppItemData = &m_aShoptabs[tabIdx].items[dwSlotPos];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
//
|
||||
//BOOL CPythonShop::CheckSlotIndex(DWORD dwSlotPos)
|
||||
//{
|
||||
// if (dwSlotPos >= SHOP_HOST_ITEM_MAX_NUM * SHOP_TAB_COUNT_MAX)
|
||||
// return FALSE;
|
||||
//
|
||||
// return TRUE;
|
||||
//}
|
||||
|
||||
void CPythonShop::ClearPrivateShopStock()
|
||||
{
|
||||
m_PrivateShopItemStock.clear();
|
||||
}
|
||||
void CPythonShop::AddPrivateShopItemStock(TItemPos ItemPos, BYTE dwDisplayPos, DWORD dwPrice)
|
||||
{
|
||||
DelPrivateShopItemStock(ItemPos);
|
||||
|
||||
TShopItemTable SellingItem;
|
||||
SellingItem.vnum = 0;
|
||||
SellingItem.count = 0;
|
||||
SellingItem.pos = ItemPos;
|
||||
SellingItem.price = dwPrice;
|
||||
SellingItem.display_pos = dwDisplayPos;
|
||||
m_PrivateShopItemStock.insert(std::make_pair(ItemPos, SellingItem));
|
||||
}
|
||||
void CPythonShop::DelPrivateShopItemStock(TItemPos ItemPos)
|
||||
{
|
||||
if (m_PrivateShopItemStock.end() == m_PrivateShopItemStock.find(ItemPos))
|
||||
return;
|
||||
|
||||
m_PrivateShopItemStock.erase(ItemPos);
|
||||
}
|
||||
int CPythonShop::GetPrivateShopItemPrice(TItemPos ItemPos)
|
||||
{
|
||||
TPrivateShopItemStock::iterator itor = m_PrivateShopItemStock.find(ItemPos);
|
||||
|
||||
if (m_PrivateShopItemStock.end() == itor)
|
||||
return 0;
|
||||
|
||||
TShopItemTable & rShopItemTable = itor->second;
|
||||
return rShopItemTable.price;
|
||||
}
|
||||
struct ItemStockSortFunc
|
||||
{
|
||||
bool operator() (TShopItemTable & rkLeft, TShopItemTable & rkRight)
|
||||
{
|
||||
return rkLeft.display_pos < rkRight.display_pos;
|
||||
}
|
||||
};
|
||||
void CPythonShop::BuildPrivateShop(const char * c_szName)
|
||||
{
|
||||
std::vector<TShopItemTable> ItemStock;
|
||||
ItemStock.reserve(m_PrivateShopItemStock.size());
|
||||
|
||||
TPrivateShopItemStock::iterator itor = m_PrivateShopItemStock.begin();
|
||||
for (; itor != m_PrivateShopItemStock.end(); ++itor)
|
||||
{
|
||||
ItemStock.push_back(itor->second);
|
||||
}
|
||||
|
||||
std::sort(ItemStock.begin(), ItemStock.end(), ItemStockSortFunc());
|
||||
|
||||
CPythonNetworkStream::Instance().SendBuildPrivateShopPacket(c_szName, ItemStock);
|
||||
}
|
||||
|
||||
void CPythonShop::Open(BOOL isPrivateShop, BOOL isMainPrivateShop)
|
||||
{
|
||||
m_isShoping = TRUE;
|
||||
m_isPrivateShop = isPrivateShop;
|
||||
m_isMainPlayerPrivateShop = isMainPrivateShop;
|
||||
}
|
||||
|
||||
void CPythonShop::Close()
|
||||
{
|
||||
m_isShoping = FALSE;
|
||||
m_isPrivateShop = FALSE;
|
||||
m_isMainPlayerPrivateShop = FALSE;
|
||||
}
|
||||
|
||||
BOOL CPythonShop::IsOpen()
|
||||
{
|
||||
return m_isShoping;
|
||||
}
|
||||
|
||||
BOOL CPythonShop::IsPrivateShop()
|
||||
{
|
||||
return m_isPrivateShop;
|
||||
}
|
||||
|
||||
BOOL CPythonShop::IsMainPlayerPrivateShop()
|
||||
{
|
||||
return m_isMainPlayerPrivateShop;
|
||||
}
|
||||
|
||||
void CPythonShop::Clear()
|
||||
{
|
||||
m_isShoping = FALSE;
|
||||
m_isPrivateShop = FALSE;
|
||||
m_isMainPlayerPrivateShop = FALSE;
|
||||
ClearPrivateShopStock();
|
||||
m_bTabCount = 1;
|
||||
|
||||
for (int i = 0; i < SHOP_TAB_COUNT_MAX; i++)
|
||||
memset (m_aShoptabs[i].items, 0, sizeof(TShopItemData) * SHOP_HOST_ITEM_MAX_NUM);
|
||||
}
|
||||
|
||||
CPythonShop::CPythonShop(void)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
CPythonShop::~CPythonShop(void)
|
||||
{
|
||||
}
|
||||
|
||||
PyObject * shopOpen(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int isPrivateShop = false;
|
||||
PyTuple_GetInteger(poArgs, 0, &isPrivateShop);
|
||||
int isMainPrivateShop = false;
|
||||
PyTuple_GetInteger(poArgs, 1, &isMainPrivateShop);
|
||||
|
||||
CPythonShop& rkShop=CPythonShop::Instance();
|
||||
rkShop.Open(isPrivateShop, isMainPrivateShop);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * shopClose(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonShop& rkShop=CPythonShop::Instance();
|
||||
rkShop.Close();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * shopIsOpen(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonShop& rkShop=CPythonShop::Instance();
|
||||
return Py_BuildValue("i", rkShop.IsOpen());
|
||||
}
|
||||
|
||||
PyObject * shopIsPrviateShop(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonShop& rkShop=CPythonShop::Instance();
|
||||
return Py_BuildValue("i", rkShop.IsPrivateShop());
|
||||
}
|
||||
|
||||
PyObject * shopIsMainPlayerPrivateShop(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonShop& rkShop=CPythonShop::Instance();
|
||||
return Py_BuildValue("i", rkShop.IsMainPlayerPrivateShop());
|
||||
}
|
||||
|
||||
PyObject * shopGetItemID(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int nPos;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &nPos))
|
||||
return Py_BuildException();
|
||||
|
||||
const TShopItemData * c_pItemData;
|
||||
if (CPythonShop::Instance().GetItemData(nPos, &c_pItemData))
|
||||
return Py_BuildValue("i", c_pItemData->vnum);
|
||||
|
||||
return Py_BuildValue("i", 0);
|
||||
}
|
||||
|
||||
PyObject * shopGetItemCount(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
|
||||
return Py_BuildException();
|
||||
|
||||
const TShopItemData * c_pItemData;
|
||||
if (CPythonShop::Instance().GetItemData(iIndex, &c_pItemData))
|
||||
return Py_BuildValue("i", c_pItemData->count);
|
||||
|
||||
return Py_BuildValue("i", 0);
|
||||
}
|
||||
|
||||
PyObject * shopGetItemPrice(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
|
||||
return Py_BuildException();
|
||||
|
||||
const TShopItemData * c_pItemData;
|
||||
if (CPythonShop::Instance().GetItemData(iIndex, &c_pItemData))
|
||||
return Py_BuildValue("i", c_pItemData->price);
|
||||
|
||||
return Py_BuildValue("i", 0);
|
||||
}
|
||||
|
||||
PyObject * shopGetItemMetinSocket(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
|
||||
return Py_BuildException();
|
||||
int iMetinSocketIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &iMetinSocketIndex))
|
||||
return Py_BuildException();
|
||||
|
||||
const TShopItemData * c_pItemData;
|
||||
if (CPythonShop::Instance().GetItemData(iIndex, &c_pItemData))
|
||||
return Py_BuildValue("i", c_pItemData->alSockets[iMetinSocketIndex]);
|
||||
|
||||
return Py_BuildValue("i", 0);
|
||||
}
|
||||
|
||||
PyObject * shopGetItemAttribute(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
int iIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
|
||||
return Py_BuildException();
|
||||
int iAttrSlotIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &iAttrSlotIndex))
|
||||
return Py_BuildException();
|
||||
|
||||
if (iAttrSlotIndex >= 0 && iAttrSlotIndex < ITEM_ATTRIBUTE_SLOT_MAX_NUM)
|
||||
{
|
||||
const TShopItemData * c_pItemData;
|
||||
if (CPythonShop::Instance().GetItemData(iIndex, &c_pItemData))
|
||||
return Py_BuildValue("ii", c_pItemData->aAttr[iAttrSlotIndex].bType, c_pItemData->aAttr[iAttrSlotIndex].sValue);
|
||||
}
|
||||
|
||||
return Py_BuildValue("ii", 0, 0);
|
||||
}
|
||||
|
||||
PyObject * shopClearPrivateShopStock(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
CPythonShop::Instance().ClearPrivateShopStock();
|
||||
return Py_BuildNone();
|
||||
}
|
||||
PyObject * shopAddPrivateShopItemStock(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
BYTE bItemWindowType;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &bItemWindowType))
|
||||
return Py_BuildException();
|
||||
WORD wItemSlotIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &wItemSlotIndex))
|
||||
return Py_BuildException();
|
||||
int iDisplaySlotIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 2, &iDisplaySlotIndex))
|
||||
return Py_BuildException();
|
||||
int iPrice;
|
||||
if (!PyTuple_GetInteger(poArgs, 3, &iPrice))
|
||||
return Py_BuildException();
|
||||
|
||||
CPythonShop::Instance().AddPrivateShopItemStock(TItemPos(bItemWindowType, wItemSlotIndex), iDisplaySlotIndex, iPrice);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
PyObject * shopDelPrivateShopItemStock(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
BYTE bItemWindowType;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &bItemWindowType))
|
||||
return Py_BuildException();
|
||||
WORD wItemSlotIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &wItemSlotIndex))
|
||||
return Py_BuildException();
|
||||
|
||||
CPythonShop::Instance().DelPrivateShopItemStock(TItemPos(bItemWindowType, wItemSlotIndex));
|
||||
return Py_BuildNone();
|
||||
}
|
||||
PyObject * shopGetPrivateShopItemPrice(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
BYTE bItemWindowType;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &bItemWindowType))
|
||||
return Py_BuildException();
|
||||
WORD wItemSlotIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &wItemSlotIndex))
|
||||
return Py_BuildException();
|
||||
|
||||
int iValue = CPythonShop::Instance().GetPrivateShopItemPrice(TItemPos(bItemWindowType, wItemSlotIndex));
|
||||
return Py_BuildValue("i", iValue);
|
||||
}
|
||||
PyObject * shopBuildPrivateShop(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
char * szName;
|
||||
if (!PyTuple_GetString(poArgs, 0, &szName))
|
||||
return Py_BuildException();
|
||||
|
||||
CPythonShop::Instance().BuildPrivateShop(szName);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject * shopGetTabCount(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
return Py_BuildValue("i", CPythonShop::instance().GetTabCount());
|
||||
}
|
||||
|
||||
PyObject * shopGetTabName(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
BYTE bTabIdx;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &bTabIdx))
|
||||
return Py_BuildException();
|
||||
|
||||
return Py_BuildValue("s", CPythonShop::instance().GetTabName(bTabIdx));
|
||||
}
|
||||
|
||||
PyObject * shopGetTabCoinType(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
BYTE bTabIdx;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &bTabIdx))
|
||||
return Py_BuildException();
|
||||
|
||||
return Py_BuildValue("i", CPythonShop::instance().GetTabCoinType(bTabIdx));
|
||||
}
|
||||
|
||||
void initshop()
|
||||
{
|
||||
static PyMethodDef s_methods[] =
|
||||
{
|
||||
// Shop
|
||||
{ "Open", shopOpen, METH_VARARGS },
|
||||
{ "Close", shopClose, METH_VARARGS },
|
||||
{ "IsOpen", shopIsOpen, METH_VARARGS },
|
||||
{ "IsPrivateShop", shopIsPrviateShop, METH_VARARGS },
|
||||
{ "IsMainPlayerPrivateShop", shopIsMainPlayerPrivateShop, METH_VARARGS },
|
||||
{ "GetItemID", shopGetItemID, METH_VARARGS },
|
||||
{ "GetItemCount", shopGetItemCount, METH_VARARGS },
|
||||
{ "GetItemPrice", shopGetItemPrice, METH_VARARGS },
|
||||
{ "GetItemMetinSocket", shopGetItemMetinSocket, METH_VARARGS },
|
||||
{ "GetItemAttribute", shopGetItemAttribute, METH_VARARGS },
|
||||
{ "GetTabCount", shopGetTabCount, METH_VARARGS },
|
||||
{ "GetTabName", shopGetTabName, METH_VARARGS },
|
||||
{ "GetTabCoinType", shopGetTabCoinType, METH_VARARGS },
|
||||
|
||||
// Private Shop
|
||||
{ "ClearPrivateShopStock", shopClearPrivateShopStock, METH_VARARGS },
|
||||
{ "AddPrivateShopItemStock", shopAddPrivateShopItemStock, METH_VARARGS },
|
||||
{ "DelPrivateShopItemStock", shopDelPrivateShopItemStock, METH_VARARGS },
|
||||
{ "GetPrivateShopItemPrice", shopGetPrivateShopItemPrice, METH_VARARGS },
|
||||
{ "BuildPrivateShop", shopBuildPrivateShop, METH_VARARGS },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
PyObject * poModule = Py_InitModule("shop", s_methods);
|
||||
|
||||
PyModule_AddIntConstant(poModule, "SHOP_SLOT_COUNT", SHOP_HOST_ITEM_MAX_NUM);
|
||||
PyModule_AddIntConstant(poModule, "SHOP_COIN_TYPE_GOLD", SHOP_COIN_TYPE_GOLD);
|
||||
PyModule_AddIntConstant(poModule, "SHOP_COIN_TYPE_SECONDARY_COIN", SHOP_COIN_TYPE_SECONDARY_COIN);
|
||||
}
|
||||
@@ -45,6 +45,7 @@ enum
|
||||
// Listed here as 40250 lists them; only the ported ones are defined.
|
||||
void initpack();
|
||||
void initime();
|
||||
void initshop();
|
||||
void initapp();
|
||||
void initchr();
|
||||
void initchrmgr();
|
||||
|
||||
Reference in New Issue
Block a user