port: PythonItem + item module (batch 2 P3-b)

Verbatim 40250 CPythonItem and the item Python module replace the
pending stand-in and the module stub; CPythonApplication::Create calls
m_pyItem.Create() in 40250 order. itemGetIconImage returns its handle
through Py_BuildPointer (the ILP32 int truncated it and wndMgr.SetSlot
crashed on the live inventory). CMapManager::GetNormal evaluates
CTerrain::CalculateNormal on the native height tile; the item text-tail
members stay stubs, Pick answering -1 like an empty tail map.

The fake server drops vnum 19 next to the actor at entergame and answers
CG_ITEM_PICKUP with GC_ITEM_GROUND_DEL; login_flow picks it up through
player.PickCloseItem and checks item.SelectItem(19).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-24 00:50:16 +09:00
co-authored by Claude Opus 5.5
parent f0564a7f12
commit 9298500df9
19 changed files with 2178 additions and 454 deletions
@@ -11,7 +11,6 @@ void AddStubConstants_eventMgr(PyObject* poModule);
void AddStubConstants_exchange(PyObject* poModule);
void AddStubConstants_guild(PyObject* poModule);
void AddStubConstants_ime(PyObject* poModule);
void AddStubConstants_item(PyObject* poModule);
void AddStubConstants_messenger(PyObject* poModule);
void AddStubConstants_miniMap(PyObject* poModule);
void AddStubConstants_profiler(PyObject* poModule);
@@ -370,82 +369,6 @@ PyMethodDef methods_ime[] = {
{ "EnablePaste", stub_ime_EnablePaste, METH_VARARGS },
{ NULL, NULL }
};
// 40250 UserInterface/PythonItemModule.cpp: item export names.
PyObject* stub_item_SetUseSoundFileName(PyObject*, PyObject*) { return stub_call_named("item.SetUseSoundFileName", Py_BuildNone()); }
PyObject* stub_item_SetDropSoundFileName(PyObject*, PyObject*) { return stub_call_named("item.SetDropSoundFileName", Py_BuildNone()); }
PyObject* stub_item_SelectItem(PyObject*, PyObject*) { return stub_call_named("item.SelectItem", Py_BuildNone()); }
PyObject* stub_item_GetItemName(PyObject*, PyObject*) { return stub_call_named("item.GetItemName", Py_BuildValue("s", "")); }
PyObject* stub_item_GetItemDescription(PyObject*, PyObject*) { return stub_call_named("item.GetItemDescription", Py_BuildValue("s", "")); }
PyObject* stub_item_GetItemSummary(PyObject*, PyObject*) { return stub_call_named("item.GetItemSummary", Py_BuildValue("s", "")); }
PyObject* stub_item_GetIconImage(PyObject*, PyObject*) { return stub_call_named("item.GetIconImage", Py_BuildValue("i", 0)); }
PyObject* stub_item_GetIconImageFileName(PyObject*, PyObject*) { return stub_call_named("item.GetIconImageFileName", Py_BuildValue("s", "")); }
PyObject* stub_item_GetItemSize(PyObject*, PyObject*) { return stub_call_named("item.GetItemSize", Py_BuildValue("(ii)", 0, 0)); }
PyObject* stub_item_GetItemType(PyObject*, PyObject*) { return stub_call_named("item.GetItemType", Py_BuildValue("i", 0)); }
PyObject* stub_item_GetItemSubType(PyObject*, PyObject*) { return stub_call_named("item.GetItemSubType", Py_BuildValue("i", 0)); }
PyObject* stub_item_GetIBuyItemPrice(PyObject*, PyObject*) { return stub_call_named("item.GetIBuyItemPrice", Py_BuildValue("i", 0)); }
PyObject* stub_item_GetISellItemPrice(PyObject*, PyObject*) { return stub_call_named("item.GetISellItemPrice", Py_BuildValue("i", 0)); }
PyObject* stub_item_IsAntiFlag(PyObject*, PyObject*) { return stub_call_named("item.IsAntiFlag", Py_BuildValue("i", 0)); }
PyObject* stub_item_IsFlag(PyObject*, PyObject*) { return stub_call_named("item.IsFlag", Py_BuildValue("i", 0)); }
PyObject* stub_item_IsWearableFlag(PyObject*, PyObject*) { return stub_call_named("item.IsWearableFlag", Py_BuildValue("i", 0)); }
PyObject* stub_item_Is1GoldItem(PyObject*, PyObject*) { return stub_call_named("item.Is1GoldItem", Py_BuildValue("i", 0)); }
PyObject* stub_item_GetLimit(PyObject*, PyObject*) { return stub_call_named("item.GetLimit", Py_BuildValue("ii", 0, 0)); }
PyObject* stub_item_GetAffect(PyObject*, PyObject*) { return stub_call_named("item.GetAffect", Py_BuildValue("ii", 0, 0)); }
PyObject* stub_item_GetValue(PyObject*, PyObject*) { return stub_call_named("item.GetValue", Py_BuildValue("i", 0)); }
PyObject* stub_item_GetSocket(PyObject*, PyObject*) { return stub_call_named("item.GetSocket", Py_BuildValue("i", 0)); }
PyObject* stub_item_GetIconInstance(PyObject*, PyObject*) { return stub_call_named("item.GetIconInstance", Py_BuildValue("i", 0)); }
PyObject* stub_item_GetUseType(PyObject*, PyObject*) { return stub_call_named("item.GetUseType", Py_BuildValue("s", "")); }
PyObject* stub_item_DeleteIconInstance(PyObject*, PyObject*) { return stub_call_named("item.DeleteIconInstance", Py_BuildNone()); }
PyObject* stub_item_IsEquipmentVID(PyObject*, PyObject*) { return stub_call_named("item.IsEquipmentVID", Py_BuildValue("i", 0)); }
PyObject* stub_item_IsRefineScroll(PyObject*, PyObject*) { return stub_call_named("item.IsRefineScroll", Py_BuildValue("i", 0)); }
PyObject* stub_item_IsDetachScroll(PyObject*, PyObject*) { return stub_call_named("item.IsDetachScroll", Py_BuildValue("i", 0)); }
PyObject* stub_item_IsKey(PyObject*, PyObject*) { return stub_call_named("item.IsKey", Py_BuildValue("i", 0)); }
PyObject* stub_item_IsMetin(PyObject*, PyObject*) { return stub_call_named("item.IsMetin", Py_BuildValue("i", 0)); }
PyObject* stub_item_CanAddToQuickSlotItem(PyObject*, PyObject*) { return stub_call_named("item.CanAddToQuickSlotItem", Py_BuildValue("i", 0)); }
PyObject* stub_item_Update(PyObject*, PyObject*) { return stub_call_named("item.Update", Py_BuildNone()); }
PyObject* stub_item_Render(PyObject*, PyObject*) { return stub_call_named("item.Render", Py_BuildNone()); }
PyObject* stub_item_CreateItem(PyObject*, PyObject*) { return stub_call_named("item.CreateItem", Py_BuildNone()); }
PyObject* stub_item_DeleteItem(PyObject*, PyObject*) { return stub_call_named("item.DeleteItem", Py_BuildNone()); }
PyObject* stub_item_Pick(PyObject*, PyObject*) { return stub_call_named("item.Pick", Py_BuildValue("i", 0)); }
PyObject* stub_item_LoadItemTable(PyObject*, PyObject*) { return stub_call_named("item.LoadItemTable", Py_BuildNone()); }
PyMethodDef methods_item[] = {
{ "SetUseSoundFileName", stub_item_SetUseSoundFileName, METH_VARARGS },
{ "SetDropSoundFileName", stub_item_SetDropSoundFileName, METH_VARARGS },
{ "SelectItem", stub_item_SelectItem, METH_VARARGS },
{ "GetItemName", stub_item_GetItemName, METH_VARARGS },
{ "GetItemDescription", stub_item_GetItemDescription, METH_VARARGS },
{ "GetItemSummary", stub_item_GetItemSummary, METH_VARARGS },
{ "GetIconImage", stub_item_GetIconImage, METH_VARARGS },
{ "GetIconImageFileName", stub_item_GetIconImageFileName, METH_VARARGS },
{ "GetItemSize", stub_item_GetItemSize, METH_VARARGS },
{ "GetItemType", stub_item_GetItemType, METH_VARARGS },
{ "GetItemSubType", stub_item_GetItemSubType, METH_VARARGS },
{ "GetIBuyItemPrice", stub_item_GetIBuyItemPrice, METH_VARARGS },
{ "GetISellItemPrice", stub_item_GetISellItemPrice, METH_VARARGS },
{ "IsAntiFlag", stub_item_IsAntiFlag, METH_VARARGS },
{ "IsFlag", stub_item_IsFlag, METH_VARARGS },
{ "IsWearableFlag", stub_item_IsWearableFlag, METH_VARARGS },
{ "Is1GoldItem", stub_item_Is1GoldItem, METH_VARARGS },
{ "GetLimit", stub_item_GetLimit, METH_VARARGS },
{ "GetAffect", stub_item_GetAffect, METH_VARARGS },
{ "GetValue", stub_item_GetValue, METH_VARARGS },
{ "GetSocket", stub_item_GetSocket, METH_VARARGS },
{ "GetIconInstance", stub_item_GetIconInstance, METH_VARARGS },
{ "GetUseType", stub_item_GetUseType, METH_VARARGS },
{ "DeleteIconInstance", stub_item_DeleteIconInstance, METH_VARARGS },
{ "IsEquipmentVID", stub_item_IsEquipmentVID, METH_VARARGS },
{ "IsRefineScroll", stub_item_IsRefineScroll, METH_VARARGS },
{ "IsDetachScroll", stub_item_IsDetachScroll, METH_VARARGS },
{ "IsKey", stub_item_IsKey, METH_VARARGS },
{ "IsMetin", stub_item_IsMetin, METH_VARARGS },
{ "CanAddToQuickSlotItem", stub_item_CanAddToQuickSlotItem, METH_VARARGS },
{ "Update", stub_item_Update, METH_VARARGS },
{ "Render", stub_item_Render, METH_VARARGS },
{ "CreateItem", stub_item_CreateItem, METH_VARARGS },
{ "DeleteItem", stub_item_DeleteItem, METH_VARARGS },
{ "Pick", stub_item_Pick, METH_VARARGS },
{ "LoadItemTable", stub_item_LoadItemTable, METH_VARARGS },
{ NULL, NULL }
};
// 40250 UserInterface/PythonMessenger.cpp: messenger export names.
PyObject* stub_messenger_RemoveFriend(PyObject*, PyObject*) { return stub_call_named("messenger.RemoveFriend", Py_BuildNone()); }
PyObject* stub_messenger_IsFriendByName(PyObject*, PyObject*) { return stub_call_named("messenger.IsFriendByName", Py_BuildValue("i", 0)); }
@@ -890,11 +813,6 @@ void init_2v0_gameplay_stubs() {
PyModule_AddIntConstant(module, "__port_stub__", 1);
AddStubConstants_ime(module);
}
{
PyObject* module = Py_InitModule("item", methods_item);
PyModule_AddIntConstant(module, "__port_stub__", 1);
AddStubConstants_item(module);
}
{
PyObject* module = Py_InitModule("messenger", methods_messenger);
PyModule_AddIntConstant(module, "__port_stub__", 1);