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:
shenlei
2026-09-24 09:30:47 +09:00
co-authored by Claude Opus 5.5
parent 85e176bdd5
commit a12e7fea42
16 changed files with 1060 additions and 115 deletions
@@ -47,7 +47,12 @@
"status": "TODO"
},
"CPythonApplication::SetMouseHandler": {
"status": "TODO"
"status": "ADAPTED",
"impl": [
"extension/src/platform/UserInterface/PythonApplication.cpp:SetMouseHandler"
],
"note": "Body verbatim on a file-static m_poMouseHandler (no application object yet); SetCursorNum calls its ChangeCursor.",
"test": "extension/tests/port_login_flow_test.cpp (step 10)"
},
"CPythonApplication::CheckDeviceState": {
"status": "TODO"
@@ -0,0 +1,72 @@
{
"reference": "UserInterface/PythonApplicationCursor.cpp",
"reference_sha256": "acd34facc55665509839d75c04feb0af074d6db40f39195c01af492a40b31e93",
"priority": "P4",
"contracts": [],
"functions": {
"CPythonApplication::CreateCursors": {
"status": "N_A",
"note": "Win32 LoadImage/DestroyCursor of the IDC_CURSOR_* resources; the host draws no hardware cursor, so SetCursorNum treats every shape in [0, CURSOR_COUNT) as loaded."
},
"CPythonApplication::DestroyCursors": {
"status": "N_A",
"note": "Win32 LoadImage/DestroyCursor of the IDC_CURSOR_* resources; the host draws no hardware cursor, so SetCursorNum treats every shape in [0, CURSOR_COUNT) as loaded."
},
"CPythonApplication::SetCursorVisible": {
"status": "ADAPTED",
"impl": [
"extension/src/platform/UserInterface/PythonApplication.cpp:SetCursorVisible"
],
"note": "Body verbatim in the platform CPythonApplication stand-in on file-static members (there is no application object yet); ShowCursor/SetCursor calls dropped.",
"test": "extension/tests/port_login_flow_test.cpp (step 10: uishop reads app.GetCursor)"
},
"CPythonApplication::GetCursorVisible": {
"status": "ADAPTED",
"impl": [
"extension/src/platform/UserInterface/PythonApplication.cpp:GetCursorVisible"
],
"note": "Body verbatim in the platform CPythonApplication stand-in on file-static members (there is no application object yet); ShowCursor/SetCursor calls dropped.",
"test": "extension/tests/port_login_flow_test.cpp (step 10: uishop reads app.GetCursor)"
},
"CPythonApplication::GetLiarCursorOn": {
"status": "ADAPTED",
"impl": [
"extension/src/platform/UserInterface/PythonApplication.cpp:GetLiarCursorOn"
],
"note": "Body verbatim in the platform CPythonApplication stand-in on file-static members (there is no application object yet); ShowCursor/SetCursor calls dropped.",
"test": "extension/tests/port_login_flow_test.cpp (step 10: uishop reads app.GetCursor)"
},
"CPythonApplication::GetCursorMode": {
"status": "ADAPTED",
"impl": [
"extension/src/platform/UserInterface/PythonApplication.cpp:GetCursorMode"
],
"note": "Body verbatim in the platform CPythonApplication stand-in on file-static members (there is no application object yet); ShowCursor/SetCursor calls dropped.",
"test": "extension/tests/port_login_flow_test.cpp (step 10: uishop reads app.GetCursor)"
},
"CPythonApplication::__IsContinuousChangeTypeCursor": {
"status": "ADAPTED",
"impl": [
"extension/src/platform/UserInterface/PythonApplication.cpp:__IsContinuousChangeTypeCursor"
],
"note": "Body verbatim in the platform CPythonApplication stand-in on file-static members (there is no application object yet); ShowCursor/SetCursor calls dropped.",
"test": "extension/tests/port_login_flow_test.cpp (step 10: uishop reads app.GetCursor)"
},
"CPythonApplication::SetCursorNum": {
"status": "ADAPTED",
"impl": [
"extension/src/platform/UserInterface/PythonApplication.cpp:SetCursorNum"
],
"note": "Body verbatim in the platform CPythonApplication stand-in on file-static members (there is no application object yet); ShowCursor/SetCursor calls dropped.",
"test": "extension/tests/port_login_flow_test.cpp (step 10: uishop reads app.GetCursor)"
},
"CPythonApplication::SetCursorMode": {
"status": "ADAPTED",
"impl": [
"extension/src/platform/UserInterface/PythonApplication.cpp:SetCursorMode"
],
"note": "Body verbatim in the platform CPythonApplication stand-in on file-static members (there is no application object yet); ShowCursor/SetCursor calls dropped.",
"test": "extension/tests/port_login_flow_test.cpp (step 10: uishop reads app.GetCursor)"
}
}
}
@@ -0,0 +1,236 @@
{
"reference": "UserInterface/PythonShop.cpp",
"reference_sha256": "23c46a5fe95a979c2be6a52fbd4699e6cba6c6a66dca10bc2dc7d720017bb2c5",
"priority": "P3",
"contracts": [],
"functions": {
"CPythonShop::SetTabCoinType": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::SetTabCoinType"
]
},
"CPythonShop::GetTabCoinType": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::GetTabCoinType"
]
},
"CPythonShop::SetTabName": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::SetTabName"
]
},
"CPythonShop::GetTabName": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::GetTabName"
]
},
"CPythonShop::SetItemData": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::SetItemData"
]
},
"CPythonShop::GetItemData": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::GetItemData"
]
},
"CPythonShop::ClearPrivateShopStock": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::ClearPrivateShopStock"
]
},
"CPythonShop::AddPrivateShopItemStock": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::AddPrivateShopItemStock"
]
},
"CPythonShop::DelPrivateShopItemStock": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::DelPrivateShopItemStock"
]
},
"CPythonShop::GetPrivateShopItemPrice": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::GetPrivateShopItemPrice"
]
},
"CPythonShop::BuildPrivateShop": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::BuildPrivateShop"
]
},
"CPythonShop::Open": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::Open"
]
},
"CPythonShop::Close": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::Close"
]
},
"CPythonShop::IsOpen": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::IsOpen"
]
},
"CPythonShop::IsPrivateShop": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::IsPrivateShop"
]
},
"CPythonShop::IsMainPlayerPrivateShop": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::IsMainPlayerPrivateShop"
]
},
"CPythonShop::Clear": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::Clear"
]
},
"CPythonShop::CPythonShop": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::CPythonShop"
]
},
"CPythonShop::~CPythonShop": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:CPythonShop::~CPythonShop"
]
},
"shopOpen": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopOpen"
]
},
"shopClose": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopClose"
]
},
"shopIsOpen": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopIsOpen"
]
},
"shopIsPrviateShop": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopIsPrviateShop"
]
},
"shopIsMainPlayerPrivateShop": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopIsMainPlayerPrivateShop"
]
},
"shopGetItemID": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopGetItemID"
]
},
"shopGetItemCount": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopGetItemCount"
]
},
"shopGetItemPrice": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopGetItemPrice"
]
},
"shopGetItemMetinSocket": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopGetItemMetinSocket"
]
},
"shopGetItemAttribute": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopGetItemAttribute"
]
},
"shopClearPrivateShopStock": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopClearPrivateShopStock"
]
},
"shopAddPrivateShopItemStock": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopAddPrivateShopItemStock"
]
},
"shopDelPrivateShopItemStock": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopDelPrivateShopItemStock"
]
},
"shopGetPrivateShopItemPrice": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopGetPrivateShopItemPrice"
]
},
"shopBuildPrivateShop": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopBuildPrivateShop"
]
},
"shopGetTabCount": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopGetTabCount"
]
},
"shopGetTabName": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopGetTabName"
]
},
"shopGetTabCoinType": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:shopGetTabCoinType"
]
},
"initshop": {
"status": "PORTED",
"impl": [
"extension/src/port/UserInterface/PythonShop.cpp:initshop"
]
}
}
}