port: P3-d PythonTextTail + textTail module (1:1 40250)
Copy PythonTextTail.cpp/PythonTextTailModule.cpp verbatim, drop the pending stand-in and the textTail module stub, register initTextTail() after initChat() and call CPythonTextTail::Initialize() in Create as 40250 does. Implement CScreen::ProjectPosition/UnprojectPosition (were stubs) with D3DXVec3Project/Unproject, and ApplicationStringTable_GetString(DWORD) over UserInterface.rc's English string table. port.login_flow projects the ground item's name tail in an ALT frame and picks it back by screen position. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
72b19b677d
commit
070a27b2cb
@@ -533,3 +533,4 @@
|
|||||||
{"time": "2026-09-24T06:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-a: ItemData, ItemManager, PythonNonPlayer + LoadLocaleData", "ported": ["GameLib/ItemData.cpp", "GameLib/ItemManager.cpp", "UserInterface/PythonNonPlayer.cpp", "UserInterface/PythonNonPlayerModule.cpp"], "adapted": ["UserInterface/PythonApplication.cpp:LoadLocaleData"], "divergent": [], "needs_live": [], "tests": ["port.login_flow 3c: item 19 Sword+9 type 1 refine 9, mob 101 Wild Dog", "port.login_live 192.168.21.203: same", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["P3-b PythonItem + PythonItemModule", "CPythonSkill (RegisterSkillDesc/Table) still pending"]}
|
{"time": "2026-09-24T06:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-a: ItemData, ItemManager, PythonNonPlayer + LoadLocaleData", "ported": ["GameLib/ItemData.cpp", "GameLib/ItemManager.cpp", "UserInterface/PythonNonPlayer.cpp", "UserInterface/PythonNonPlayerModule.cpp"], "adapted": ["UserInterface/PythonApplication.cpp:LoadLocaleData"], "divergent": [], "needs_live": [], "tests": ["port.login_flow 3c: item 19 Sword+9 type 1 refine 9, mob 101 Wild Dog", "port.login_live 192.168.21.203: same", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["P3-b PythonItem + PythonItemModule", "CPythonSkill (RegisterSkillDesc/Table) still pending"]}
|
||||||
{"time": "2026-09-24T07:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-b: PythonItem + PythonItemModule", "ported": ["UserInterface/PythonItem.cpp", "UserInterface/PythonItemModule.cpp"], "adapted": ["UserInterface/PythonItemModule.cpp:itemGetIconImage", "GameLib/MapManager.cpp:CMapManager::GetNormal"], "divergent": [], "needs_live": [], "tests": ["port.login_flow: fake GC_ITEM_GROUND_ADD vnum 19 + ownership, player.PickCloseItem -> CG_ITEM_PICKUP -> GC_ITEM_GROUND_DEL removes it", "port.login_flow: item.SelectItem(19) name/type/subtype/value", "port.login_live 192.168.21.203: passes (icon pointer truncation segfault fixed)", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["P3-c PythonExchange", "PythonTextTail item tails (Register/Delete/SetOwner/Pick still stubs)", "CEffectManager (dropitem.mse)"]}
|
{"time": "2026-09-24T07:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-b: PythonItem + PythonItemModule", "ported": ["UserInterface/PythonItem.cpp", "UserInterface/PythonItemModule.cpp"], "adapted": ["UserInterface/PythonItemModule.cpp:itemGetIconImage", "GameLib/MapManager.cpp:CMapManager::GetNormal"], "divergent": [], "needs_live": [], "tests": ["port.login_flow: fake GC_ITEM_GROUND_ADD vnum 19 + ownership, player.PickCloseItem -> CG_ITEM_PICKUP -> GC_ITEM_GROUND_DEL removes it", "port.login_flow: item.SelectItem(19) name/type/subtype/value", "port.login_live 192.168.21.203: passes (icon pointer truncation segfault fixed)", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["P3-c PythonExchange", "PythonTextTail item tails (Register/Delete/SetOwner/Pick still stubs)", "CEffectManager (dropitem.mse)"]}
|
||||||
{"time": "2026-09-24T08:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-c: PythonExchange + PythonExchangeModule", "ported": ["UserInterface/PythonExchange.cpp", "UserInterface/PythonExchangeModule.cpp"], "adapted": [], "divergent": [], "needs_live": ["exchange with a real second player"], "tests": ["port.login_flow: net.SendExchangeStartPacket -> fake GC_EXCHANGE START/ITEM_ADD/GOLD_ADD fills target side, uiexchange opens; SendExchangeExitPacket -> END closes", "port.login_live 192.168.21.203: passes", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["PythonTextTail item tails", "PythonMiniMap", "CEffectManager", "CPythonSkill"]}
|
{"time": "2026-09-24T08:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-c: PythonExchange + PythonExchangeModule", "ported": ["UserInterface/PythonExchange.cpp", "UserInterface/PythonExchangeModule.cpp"], "adapted": [], "divergent": [], "needs_live": ["exchange with a real second player"], "tests": ["port.login_flow: net.SendExchangeStartPacket -> fake GC_EXCHANGE START/ITEM_ADD/GOLD_ADD fills target side, uiexchange opens; SendExchangeExitPacket -> END closes", "port.login_live 192.168.21.203: passes", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["PythonTextTail item tails", "PythonMiniMap", "CEffectManager", "CPythonSkill"]}
|
||||||
|
{"time": "2026-09-24T09:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-d: PythonTextTail + textTail module", "ported": ["UserInterface/PythonTextTail.cpp", "UserInterface/PythonTextTailModule.cpp"], "adapted": ["EterLib/GrpScreen.cpp:CScreen::ProjectPosition", "EterLib/GrpScreen.cpp:CScreen::UnprojectPosition", "UserInterface/UserInterface.cpp:ApplicationStringTable_GetString", "UserInterface/UserInterface.cpp:ApplicationStringTable_GetStringz"], "divergent": [], "needs_live": [], "tests": ["port.login_flow: ground item name tail registered, ALT frame projects it, CPythonTextTail::Pick returns the item VID, deleted on pickup", "port.login_live 192.168.21.203: passes", "ctest all 19/19, python_game_render_test offline PASS", "port_map.py check: 0 errors"], "todo": ["PythonMiniMap", "CEffectManager", "CPythonSkill"]}
|
||||||
|
|||||||
@@ -115,10 +115,20 @@
|
|||||||
"status": "TODO"
|
"status": "TODO"
|
||||||
},
|
},
|
||||||
"CScreen::ProjectPosition": {
|
"CScreen::ProjectPosition": {
|
||||||
"status": "TODO"
|
"status": "ADAPTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/platform/EterLib/GrpScreen.cpp:CScreen::ProjectPosition"
|
||||||
|
],
|
||||||
|
"note": "Body verbatim; D3DXVec3Project/Unproject come from port/common/D3DXMath.cpp (D3DX semantics, null matrix = identity).",
|
||||||
|
"test": "extension/tests/port_login_flow_test.cpp ground-item step (port.login_flow: ALT frame projects the item name tail, textTail Pick returns the ground item VID)"
|
||||||
},
|
},
|
||||||
"CScreen::UnprojectPosition": {
|
"CScreen::UnprojectPosition": {
|
||||||
"status": "TODO"
|
"status": "ADAPTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/platform/EterLib/GrpScreen.cpp:CScreen::UnprojectPosition"
|
||||||
|
],
|
||||||
|
"note": "Body verbatim; D3DXVec3Project/Unproject come from port/common/D3DXMath.cpp (D3DX semantics, null matrix = identity).",
|
||||||
|
"test": "extension/tests/port_login_flow_test.cpp ground-item step (port.login_flow: ALT frame projects the item name tail, textTail Pick returns the ground item VID)"
|
||||||
},
|
},
|
||||||
"CScreen::SetColorOperation": {
|
"CScreen::SetColorOperation": {
|
||||||
"status": "TODO"
|
"status": "TODO"
|
||||||
|
|||||||
@@ -0,0 +1,248 @@
|
|||||||
|
{
|
||||||
|
"reference": "UserInterface/PythonTextTail.cpp",
|
||||||
|
"reference_sha256": "30392fd529a043f638bc7ada3e5177f78a9424857911b2903f3f9d7cec7aba7a",
|
||||||
|
"priority": "P3",
|
||||||
|
"contracts": [],
|
||||||
|
"functions": {
|
||||||
|
"TextTail_GetLivingTime": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:TextTail_GetLivingTime"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"TextTail_SetLivingTime": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:TextTail_SetLivingTime"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::GetInfo": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::GetInfo"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::UpdateAllTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::UpdateAllTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::UpdateShowingTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::UpdateShowingTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::UpdateTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::UpdateTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::ArrangeTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::ArrangeTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::Render": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::Render"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::RenderTextTailBox": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::RenderTextTailBox"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::RenderTextTailName": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::RenderTextTailName"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::HideAllTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::HideAllTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::UpdateDistance": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::UpdateDistance"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::ShowAllTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::ShowAllTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::ShowCharacterTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::ShowCharacterTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::ShowItemTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::ShowItemTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::isIn": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::isIn"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::RegisterCharacterTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::RegisterCharacterTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::RegisterItemTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::RegisterItemTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::RegisterChatTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::RegisterChatTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::RegisterInfoTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::RegisterInfoTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::GetTextTailPosition": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::GetTextTailPosition"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::IsChatTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::IsChatTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::SetCharacterTextTailColor": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::SetCharacterTextTailColor"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::SetItemTextTailOwner": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::SetItemTextTailOwner"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::DeleteCharacterTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::DeleteCharacterTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::DeleteItemTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::DeleteItemTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::RegisterTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::RegisterTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::DeleteTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::DeleteTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::Pick": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::Pick"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::SelectItemName": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::SelectItemName"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::AttachTitle": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::AttachTitle"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::DetachTitle": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::DetachTitle"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::EnablePKTitle": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::EnablePKTitle"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::AttachLevel": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::AttachLevel"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::DetachLevel": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::DetachLevel"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::Initialize": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::Initialize"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::Destroy": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::Destroy"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::Clear": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::Clear"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::CPythonTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::CPythonTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CPythonTextTail::~CPythonTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTail.cpp:CPythonTextTail::~CPythonTextTail"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
{
|
||||||
|
"reference": "UserInterface/PythonTextTailModule.cpp",
|
||||||
|
"reference_sha256": "bd7149ddc99091064e9e011894562e6adae137efec7ec10c42400c2b23bba796",
|
||||||
|
"priority": "P4",
|
||||||
|
"contracts": [],
|
||||||
|
"functions": {
|
||||||
|
"textTailClear": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailClear"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailUpdateAllTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailUpdateAllTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailUpdateShowingTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailUpdateShowingTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailRender": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailRender"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailRegisterCharacterTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailRegisterCharacterTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailGetPosition": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailGetPosition"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailIsChat": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailIsChat"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailRegisterChatTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailRegisterChatTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailRegisterInfoTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailRegisterInfoTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailAttachTitle": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailAttachTitle"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailShowCharacterTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailShowCharacterTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailShowItemTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailShowItemTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailArrangeTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailArrangeTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailHideAllTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailHideAllTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailShowAllTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailShowAllTextTail"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailPick": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailPick"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailSelectItemName": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailSelectItemName"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"textTailEnablePKTitle": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:textTailEnablePKTitle"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"initTextTail": {
|
||||||
|
"status": "PORTED",
|
||||||
|
"impl": [
|
||||||
|
"extension/src/port/UserInterface/PythonTextTailModule.cpp:initTextTail"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,78 +1,88 @@
|
|||||||
{
|
{
|
||||||
"reference": "UserInterface/UserInterface.cpp",
|
"reference": "UserInterface/UserInterface.cpp",
|
||||||
"reference_sha256": "beed987e4b1de627acafe7ea6f5fde989b8f4b33c8643fe2abb0f7152ea4a9eb",
|
"reference_sha256": "beed987e4b1de627acafe7ea6f5fde989b8f4b33c8643fe2abb0f7152ea4a9eb",
|
||||||
"priority": "P4",
|
"priority": "P4",
|
||||||
"contracts": [],
|
"contracts": [],
|
||||||
"functions": {
|
"functions": {
|
||||||
"ApplicationSetErrorString": {
|
"ApplicationSetErrorString": {
|
||||||
"status": "TODO"
|
"status": "TODO"
|
||||||
},
|
},
|
||||||
"CheckPythonLibraryFilenames": {
|
"CheckPythonLibraryFilenames": {
|
||||||
"status": "TODO"
|
"status": "TODO"
|
||||||
},
|
},
|
||||||
"ApplicationStringTable_Initialize": {
|
"ApplicationStringTable_Initialize": {
|
||||||
"status": "TODO"
|
"status": "TODO"
|
||||||
},
|
},
|
||||||
"ApplicationStringTable_GetString": {
|
"ApplicationStringTable_GetString": {
|
||||||
"status": "TODO"
|
"status": "ADAPTED",
|
||||||
},
|
"impl": [
|
||||||
"ApplicationStringTable_GetStringz": {
|
"extension/src/platform/UserInterface/UserInterface.cpp:ApplicationStringTable_GetString"
|
||||||
"status": "TODO"
|
],
|
||||||
},
|
"note": "Only the (DWORD) overload: LoadString becomes a switch over UserInterface.rc's LANG_ENGLISH/SUBLANG_ENGLISH_US STRINGTABLE. The (DWORD, LPCSTR) metin2client.dat overload is declared but not defined (no caller ported yet).",
|
||||||
"PackInitialize": {
|
"test": "extension/tests/port_login_flow_test.cpp ground-item step (port.login_flow: ALT frame projects the item name tail, textTail Pick returns the ground item VID); PythonTextTail::SetItemTextTailOwner uses IDS_POSSESSIVE_MORPHENE"
|
||||||
"impl": [
|
},
|
||||||
"extension/src/platform/UserInterface/UserInterface.cpp:PackInitialize"
|
"ApplicationStringTable_GetStringz": {
|
||||||
],
|
"status": "ADAPTED",
|
||||||
"status": "ADAPTED",
|
"impl": [
|
||||||
"note": "platform PackInitialize: Index pack names resolved to the on-disk .eix spelling case-insensitively; no LogBoxf; CTextFileLoader::SetCacheMode / CSoundData::SetPackMode not called (units not ported, neither affects pack registration)",
|
"extension/src/platform/UserInterface/UserInterface.cpp:ApplicationStringTable_GetStringz"
|
||||||
"test": "extension/tests/port_eterpack_test.cpp (103 packs, 54891 entries, first-registered wins, 4 SECURITY rejects); extension/tests/proto_test.cpp (40250 locale/en item_proto/mob_proto through pack://)"
|
],
|
||||||
},
|
"note": "Only the (DWORD) overload: LoadString becomes a switch over UserInterface.rc's LANG_ENGLISH/SUBLANG_ENGLISH_US STRINGTABLE. The (DWORD, LPCSTR) metin2client.dat overload is declared but not defined (no caller ported yet).",
|
||||||
"RunMainScript": {
|
"test": "extension/tests/port_login_flow_test.cpp ground-item step (port.login_flow: ALT frame projects the item name tail, textTail Pick returns the ground item VID); PythonTextTail::SetItemTextTailOwner uses IDS_POSSESSIVE_MORPHENE"
|
||||||
"impl": [
|
},
|
||||||
"extension/src/platform/ScriptLib/PythonBoot.cpp:PythonBoot::RunMainScript"
|
"PackInitialize": {
|
||||||
],
|
"impl": [
|
||||||
"status": "ADAPTED",
|
"extension/src/platform/UserInterface/UserInterface.cpp:PackInitialize"
|
||||||
"note": "40250 runs it on Main()'s stack and takes the CPythonLauncher by reference; Godot owns this process, so PythonBoot::Start holds the launcher and RunMainScript takes only the command line plus a std::string* for the text 40250 shows in LogBox's message box. Of the 37 module initializers only initpack() is called — the rest are 2V slices, which is why system.py still stops at its first import. RegisterCommandLine passes the line through unchanged: the -cs/-ncs auto-login decoding needs EterBase/Utils.cpp SplitLine and EterLib/Util.cpp base64_decode, both still TODO (批次 2V1). '--pause-before-create-window' (system(\"pause\")) and the XTrap init check are dropped: no console and no XTrap on this platform.",
|
],
|
||||||
"test": "project/python_host_test.gd (godot --headless --path project --script python_host_test.gd) and the same check through MT_TEST_MODE=python in project/client_main.gd -> system.py stops at ImportError: No module named app, the same point as ctest port.python_launcher"
|
"status": "ADAPTED",
|
||||||
},
|
"note": "platform PackInitialize: Index pack names resolved to the on-disk .eix spelling case-insensitively; no LogBoxf; CTextFileLoader::SetCacheMode / CSoundData::SetPackMode not called (units not ported, neither affects pack registration)",
|
||||||
"Main": {
|
"test": "extension/tests/port_eterpack_test.cpp (103 packs, 54891 entries, first-registered wins, 4 SECURITY rejects); extension/tests/proto_test.cpp (40250 locale/en item_proto/mob_proto through pack://)"
|
||||||
"status": "TODO"
|
},
|
||||||
},
|
"RunMainScript": {
|
||||||
"CreateMetin2GameMutex": {
|
"impl": [
|
||||||
"status": "TODO"
|
"extension/src/platform/ScriptLib/PythonBoot.cpp:PythonBoot::RunMainScript"
|
||||||
},
|
],
|
||||||
"DestroyMetin2GameMutex": {
|
"status": "ADAPTED",
|
||||||
"status": "TODO"
|
"note": "40250 runs it on Main()'s stack and takes the CPythonLauncher by reference; Godot owns this process, so PythonBoot::Start holds the launcher and RunMainScript takes only the command line plus a std::string* for the text 40250 shows in LogBox's message box. Of the 37 module initializers only initpack() is called — the rest are 2V slices, which is why system.py still stops at its first import. RegisterCommandLine passes the line through unchanged: the -cs/-ncs auto-login decoding needs EterBase/Utils.cpp SplitLine and EterLib/Util.cpp base64_decode, both still TODO (批次 2V1). '--pause-before-create-window' (system(\"pause\")) and the XTrap init check are dropped: no console and no XTrap on this platform.",
|
||||||
},
|
"test": "project/python_host_test.gd (godot --headless --path project --script python_host_test.gd) and the same check through MT_TEST_MODE=python in project/client_main.gd -> system.py stops at ImportError: No module named app, the same point as ctest port.python_launcher"
|
||||||
"__ErrorPythonLibraryIsNotExist": {
|
},
|
||||||
"status": "TODO"
|
"Main": {
|
||||||
},
|
"status": "TODO"
|
||||||
"__IsTimeStampOption": {
|
},
|
||||||
"status": "TODO"
|
"CreateMetin2GameMutex": {
|
||||||
},
|
"status": "TODO"
|
||||||
"__PrintTimeStamp": {
|
},
|
||||||
"status": "TODO"
|
"DestroyMetin2GameMutex": {
|
||||||
},
|
"status": "TODO"
|
||||||
"__IsLocaleOption": {
|
},
|
||||||
"status": "TODO"
|
"__ErrorPythonLibraryIsNotExist": {
|
||||||
},
|
"status": "TODO"
|
||||||
"__IsLocaleVersion": {
|
},
|
||||||
"status": "TODO"
|
"__IsTimeStampOption": {
|
||||||
},
|
"status": "TODO"
|
||||||
"__IsOpenIDAuthKeyOption": {
|
},
|
||||||
"status": "TODO"
|
"__PrintTimeStamp": {
|
||||||
},
|
"status": "TODO"
|
||||||
"__IsOpenIDTestOption": {
|
},
|
||||||
"status": "TODO"
|
"__IsLocaleOption": {
|
||||||
},
|
"status": "TODO"
|
||||||
"WinMain": {
|
},
|
||||||
"status": "TODO"
|
"__IsLocaleVersion": {
|
||||||
},
|
"status": "TODO"
|
||||||
"GrannyError": {
|
},
|
||||||
"status": "TODO"
|
"__IsOpenIDAuthKeyOption": {
|
||||||
},
|
"status": "TODO"
|
||||||
"Setup": {
|
},
|
||||||
"status": "TODO"
|
"__IsOpenIDTestOption": {
|
||||||
|
"status": "TODO"
|
||||||
|
},
|
||||||
|
"WinMain": {
|
||||||
|
"status": "TODO"
|
||||||
|
},
|
||||||
|
"GrannyError": {
|
||||||
|
"status": "TODO"
|
||||||
|
},
|
||||||
|
"Setup": {
|
||||||
|
"status": "TODO"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -440,6 +440,8 @@ extension/third_party/cpython-2.7.18/ # 静态库(2P 批次
|
|||||||
|
|
||||||
P3-c(2026-09-24):`PythonExchange.cpp` 与 `PythonExchangeModule.cpp` 原样移植(无手改),删除 pending 替身与 exchange 模块桩,`initTrade()` 按 40250 顺序在 `initNonPlayer()` 之后。假服按 `CInputMain::Exchange` 应答:`CG_EXCHANGE` START 回 `GC_EXCHANGE` START(arg1 = 请求的 vid)+ 对方 ITEM_ADD(vnum 19,格 0)+ GOLD_ADD 1000,CANCEL 回 END;`port.login_flow` 用 `net.SendExchangeStartPacket` 开交易,验证 `exchange.isTrading/GetItemVnumFromTarget/GetItemCountFromTarget/GetElkFromTarget`,uiexchange 打开后 `net.SendExchangeExitPacket` 收到 END 关闭。注意:40250 `SendExchangeExitPacket` 的 arg1 未初始化(原样保留,假服不记录它);`uiexchange.CloseDialog` 调 `wndMgr.OnceIgnoreMouseLeftButtonUpEvent()`,测试先消耗这次被忽略的左键抬起,否则下一次点地的抬起被吞、角色一直按住行走。下一步 `PythonTextTail`(物品名牌)与 `PythonMiniMap`。
|
P3-c(2026-09-24):`PythonExchange.cpp` 与 `PythonExchangeModule.cpp` 原样移植(无手改),删除 pending 替身与 exchange 模块桩,`initTrade()` 按 40250 顺序在 `initNonPlayer()` 之后。假服按 `CInputMain::Exchange` 应答:`CG_EXCHANGE` START 回 `GC_EXCHANGE` START(arg1 = 请求的 vid)+ 对方 ITEM_ADD(vnum 19,格 0)+ GOLD_ADD 1000,CANCEL 回 END;`port.login_flow` 用 `net.SendExchangeStartPacket` 开交易,验证 `exchange.isTrading/GetItemVnumFromTarget/GetItemCountFromTarget/GetElkFromTarget`,uiexchange 打开后 `net.SendExchangeExitPacket` 收到 END 关闭。注意:40250 `SendExchangeExitPacket` 的 arg1 未初始化(原样保留,假服不记录它);`uiexchange.CloseDialog` 调 `wndMgr.OnceIgnoreMouseLeftButtonUpEvent()`,测试先消耗这次被忽略的左键抬起,否则下一次点地的抬起被吞、角色一直按住行走。下一步 `PythonTextTail`(物品名牌)与 `PythonMiniMap`。
|
||||||
|
|
||||||
|
P3-d(2026-09-24):`PythonTextTail.cpp` 与 `PythonTextTailModule.cpp` 原样移植(无手改),删除 pending 替身(含 P3-b 的物品名牌桩)、textTail 模块桩与 `TextTail_SetLivingTime` 桩,`initTextTail()` 按 40250 顺序在 `initChat()` 之后,平台 `CPythonApplication::Create` 按原序调 `CPythonTextTail::Initialize()`。连带补齐:`CScreen::ProjectPosition/UnprojectPosition` 原样实现(此前是桩,名牌永远停在 -100,-100),`D3DXMath` 补 `D3DXVec3Project/Unproject`(D3DX 语义);`ApplicationStringTable_GetString(z)(DWORD)` 在平台 `UserInterface.cpp` 以 UserInterface.rc 英文 STRINGTABLE 代替 `LoadString`(物品归属名 "'s"),记 ADAPTED。`port.login_flow` 验证:假服地面物品注册了物品名牌(ItemTail Map 1),按住 ALT 一帧后 `game.GameWindow.OnRender` 在 `app.RenderGame` 之后投影名牌,`CPythonTextTail::Pick` 在屏幕上找回该物品 VID;拾取后名牌删除。下一步 `PythonMiniMap`。
|
||||||
|
|
||||||
每个切片都必须同时跑 legacy/port 双路回归;只有 2V3 稳定并把默认路由切到 `port` 后,才能删除总开关和剩余 legacy 宿主。
|
每个切片都必须同时跑 legacy/port 双路回归;只有 2V3 稳定并把默认路由切到 `port` 后,才能删除总开关和剩余 legacy 宿主。
|
||||||
|
|
||||||
## 5. 数据源切换:m2dev assets → 40250
|
## 5. 数据源切换:m2dev assets → 40250
|
||||||
|
|||||||
@@ -298,19 +298,37 @@ auto CScreen::GetPickingPosition(float, float *, float *, float *) -> void
|
|||||||
MT_PLATFORM_STUB();
|
MT_PLATFORM_STUB();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CScreen::ProjectPosition(float, float, float, float *, float *) -> void
|
// 40250 GrpScreen.cpp:749-779.
|
||||||
|
void CScreen::ProjectPosition(float x, float y, float z, float * pfX, float * pfY)
|
||||||
{
|
{
|
||||||
MT_PLATFORM_STUB();
|
D3DXVECTOR3 Input(x, y, z);
|
||||||
|
D3DXVECTOR3 Output;
|
||||||
|
D3DXVec3Project(&Output, &Input, &ms_Viewport, &ms_matProj, &ms_matView, &ms_matWorld);
|
||||||
|
|
||||||
|
*pfX = Output.x;
|
||||||
|
*pfY = Output.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CScreen::ProjectPosition(float, float, float, float *, float *, float *) -> void
|
void CScreen::ProjectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ)
|
||||||
{
|
{
|
||||||
MT_PLATFORM_STUB();
|
D3DXVECTOR3 Input(x, y, z);
|
||||||
|
D3DXVECTOR3 Output;
|
||||||
|
D3DXVec3Project(&Output, &Input, &ms_Viewport, &ms_matProj, &ms_matView, &ms_matWorld);
|
||||||
|
|
||||||
|
*pfX = Output.x;
|
||||||
|
*pfY = Output.y;
|
||||||
|
*pfZ = Output.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CScreen::UnprojectPosition(float, float, float, float *, float *, float *) -> void
|
void CScreen::UnprojectPosition(float x, float y, float z, float * pfX, float * pfY, float * pfZ)
|
||||||
{
|
{
|
||||||
MT_PLATFORM_STUB();
|
D3DXVECTOR3 Input(x, y, z);
|
||||||
|
D3DXVECTOR3 Output;
|
||||||
|
D3DXVec3Unproject(&Output, &Input, &ms_Viewport, &ms_matProj, &ms_matView, &ms_matWorld);
|
||||||
|
|
||||||
|
*pfX = Output.x;
|
||||||
|
*pfY = Output.y;
|
||||||
|
*pfZ = Output.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CScreen::IsLostDevice() -> BOOL
|
auto CScreen::IsLostDevice() -> BOOL
|
||||||
|
|||||||
@@ -188,12 +188,6 @@ void AddStubConstants_systemSetting(PyObject* poModule)
|
|||||||
PyModule_AddIntConstant(poModule, "WINDOW_CHAT", CPythonSystem::WINDOW_CHAT);
|
PyModule_AddIntConstant(poModule, "WINDOW_CHAT", CPythonSystem::WINDOW_CHAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 40250 UserInterface/PythonTextTailModule.cpp
|
|
||||||
void AddStubConstants_textTail(PyObject* poModule)
|
|
||||||
{
|
|
||||||
(void) poModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 40250 UserInterface/PythonNetworkDatagramModule.cpp
|
// 40250 UserInterface/PythonNetworkDatagramModule.cpp
|
||||||
void AddStubConstants_udp(PyObject* poModule)
|
void AddStubConstants_udp(PyObject* poModule)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ void AddStubConstants_shop(PyObject* poModule);
|
|||||||
void AddStubConstants_skill(PyObject* poModule);
|
void AddStubConstants_skill(PyObject* poModule);
|
||||||
void AddStubConstants_snd(PyObject* poModule);
|
void AddStubConstants_snd(PyObject* poModule);
|
||||||
void AddStubConstants_systemSetting(PyObject* poModule);
|
void AddStubConstants_systemSetting(PyObject* poModule);
|
||||||
void AddStubConstants_textTail(PyObject* poModule);
|
|
||||||
void AddStubConstants_udp(PyObject* poModule);
|
void AddStubConstants_udp(PyObject* poModule);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -691,46 +690,6 @@ PyMethodDef methods_systemSetting[] = {
|
|||||||
{ "SetShadowLevel", stub_systemSetting_SetShadowLevel, METH_VARARGS },
|
{ "SetShadowLevel", stub_systemSetting_SetShadowLevel, METH_VARARGS },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
// 40250 UserInterface/PythonTextTailModule.cpp: textTail export names.
|
|
||||||
PyObject* stub_textTail_Clear(PyObject*, PyObject*) { return stub_call_named("textTail.Clear", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_UpdateAllTextTail(PyObject*, PyObject*) { return stub_call_named("textTail.UpdateAllTextTail", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_UpdateShowingTextTail(PyObject*, PyObject*) { return stub_call_named("textTail.UpdateShowingTextTail", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_Render(PyObject*, PyObject*) { return stub_call_named("textTail.Render", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_ShowCharacterTextTail(PyObject*, PyObject*) { return stub_call_named("textTail.ShowCharacterTextTail", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_ShowItemTextTail(PyObject*, PyObject*) { return stub_call_named("textTail.ShowItemTextTail", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_GetPosition(PyObject*, PyObject*) { return stub_call_named("textTail.GetPosition", Py_BuildValue("fff", 0.0, 0.0, 0.0)); }
|
|
||||||
PyObject* stub_textTail_IsChat(PyObject*, PyObject*) { return stub_call_named("textTail.IsChat", Py_BuildValue("i", 0)); }
|
|
||||||
PyObject* stub_textTail_ArrangeTextTail(PyObject*, PyObject*) { return stub_call_named("textTail.ArrangeTextTail", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_HideAllTextTail(PyObject*, PyObject*) { return stub_call_named("textTail.HideAllTextTail", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_ShowAllTextTail(PyObject*, PyObject*) { return stub_call_named("textTail.ShowAllTextTail", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_Pick(PyObject*, PyObject*) { return stub_call_named("textTail.Pick", Py_BuildValue("i", 0)); }
|
|
||||||
PyObject* stub_textTail_SelectItemName(PyObject*, PyObject*) { return stub_call_named("textTail.SelectItemName", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_EnablePKTitle(PyObject*, PyObject*) { return stub_call_named("textTail.EnablePKTitle", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_RegisterCharacterTextTail(PyObject*, PyObject*) { return stub_call_named("textTail.RegisterCharacterTextTail", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_RegisterChatTail(PyObject*, PyObject*) { return stub_call_named("textTail.RegisterChatTail", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_RegisterInfoTail(PyObject*, PyObject*) { return stub_call_named("textTail.RegisterInfoTail", Py_BuildNone()); }
|
|
||||||
PyObject* stub_textTail_AttachTitle(PyObject*, PyObject*) { return stub_call_named("textTail.AttachTitle", Py_BuildNone()); }
|
|
||||||
PyMethodDef methods_textTail[] = {
|
|
||||||
{ "Clear", stub_textTail_Clear, METH_VARARGS },
|
|
||||||
{ "UpdateAllTextTail", stub_textTail_UpdateAllTextTail, METH_VARARGS },
|
|
||||||
{ "UpdateShowingTextTail", stub_textTail_UpdateShowingTextTail, METH_VARARGS },
|
|
||||||
{ "Render", stub_textTail_Render, METH_VARARGS },
|
|
||||||
{ "ShowCharacterTextTail", stub_textTail_ShowCharacterTextTail, METH_VARARGS },
|
|
||||||
{ "ShowItemTextTail", stub_textTail_ShowItemTextTail, METH_VARARGS },
|
|
||||||
{ "GetPosition", stub_textTail_GetPosition, METH_VARARGS },
|
|
||||||
{ "IsChat", stub_textTail_IsChat, METH_VARARGS },
|
|
||||||
{ "ArrangeTextTail", stub_textTail_ArrangeTextTail, METH_VARARGS },
|
|
||||||
{ "HideAllTextTail", stub_textTail_HideAllTextTail, METH_VARARGS },
|
|
||||||
{ "ShowAllTextTail", stub_textTail_ShowAllTextTail, METH_VARARGS },
|
|
||||||
{ "Pick", stub_textTail_Pick, METH_VARARGS },
|
|
||||||
{ "SelectItemName", stub_textTail_SelectItemName, METH_VARARGS },
|
|
||||||
{ "EnablePKTitle", stub_textTail_EnablePKTitle, METH_VARARGS },
|
|
||||||
{ "RegisterCharacterTextTail", stub_textTail_RegisterCharacterTextTail, METH_VARARGS },
|
|
||||||
{ "RegisterChatTail", stub_textTail_RegisterChatTail, METH_VARARGS },
|
|
||||||
{ "RegisterInfoTail", stub_textTail_RegisterInfoTail, METH_VARARGS },
|
|
||||||
{ "AttachTitle", stub_textTail_AttachTitle, METH_VARARGS },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
// 40250 UserInterface/PythonNetworkDatagramModule.cpp: udp export names.
|
// 40250 UserInterface/PythonNetworkDatagramModule.cpp: udp export names.
|
||||||
PyObject* stub_udp_Enable(PyObject*, PyObject*) { return stub_call_named("udp.Enable", Py_BuildNone()); }
|
PyObject* stub_udp_Enable(PyObject*, PyObject*) { return stub_call_named("udp.Enable", Py_BuildNone()); }
|
||||||
PyObject* stub_udp_Disable(PyObject*, PyObject*) { return stub_call_named("udp.Disable", Py_BuildNone()); }
|
PyObject* stub_udp_Disable(PyObject*, PyObject*) { return stub_call_named("udp.Disable", Py_BuildNone()); }
|
||||||
@@ -812,11 +771,6 @@ void init_2v0_gameplay_stubs() {
|
|||||||
PyModule_AddIntConstant(module, "__port_stub__", 1);
|
PyModule_AddIntConstant(module, "__port_stub__", 1);
|
||||||
AddStubConstants_systemSetting(module);
|
AddStubConstants_systemSetting(module);
|
||||||
}
|
}
|
||||||
{
|
|
||||||
PyObject* module = Py_InitModule("textTail", methods_textTail);
|
|
||||||
PyModule_AddIntConstant(module, "__port_stub__", 1);
|
|
||||||
AddStubConstants_textTail(module);
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
PyObject* module = Py_InitModule("udp", methods_udp);
|
PyObject* module = Py_InitModule("udp", methods_udp);
|
||||||
PyModule_AddIntConstant(module, "__port_stub__", 1);
|
PyModule_AddIntConstant(module, "__port_stub__", 1);
|
||||||
|
|||||||
@@ -351,6 +351,7 @@ bool run_main_script_body(const char* lpCmdLine, std::string* error)
|
|||||||
initNonPlayer();
|
initNonPlayer();
|
||||||
initTrade();
|
initTrade();
|
||||||
initChat();
|
initChat();
|
||||||
|
initTextTail();
|
||||||
initnet();
|
initnet();
|
||||||
initeffect();
|
initeffect();
|
||||||
initfly();
|
initfly();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "UserInterface/PythonNetworkStream.h"
|
#include "UserInterface/PythonNetworkStream.h"
|
||||||
#include "UserInterface/AccountConnector.h"
|
#include "UserInterface/AccountConnector.h"
|
||||||
#include "UserInterface/PythonItem.h"
|
#include "UserInterface/PythonItem.h"
|
||||||
|
#include "UserInterface/PythonTextTail.h"
|
||||||
#include "UserInterface/PythonSkill.h"
|
#include "UserInterface/PythonSkill.h"
|
||||||
#include "UserInterface/PythonNonPlayer.h"
|
#include "UserInterface/PythonNonPlayer.h"
|
||||||
#include "GameLib/ItemManager.h"
|
#include "GameLib/ItemManager.h"
|
||||||
@@ -124,6 +125,9 @@ bool CPythonApplication::Create(PyObject*, const char*, int, int, int)
|
|||||||
// 40250 m_pyItem.Create() (PythonApplication.cpp:1253): registers dropitem.mse with CEffectManager,
|
// 40250 m_pyItem.Create() (PythonApplication.cpp:1253): registers dropitem.mse with CEffectManager,
|
||||||
// still a platform stub.
|
// still a platform stub.
|
||||||
CPythonItem::Instance().Create();
|
CPythonItem::Instance().Create();
|
||||||
|
|
||||||
|
// 40250 PythonApplication.cpp:1260, after DefaultFont_Startup and the IME.
|
||||||
|
CPythonTextTail::Instance().Initialize();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// 40250 PythonApplication.cpp:105
|
// 40250 PythonApplication.cpp:105
|
||||||
@@ -404,7 +408,6 @@ bool LoadLocaleData(const char* localePath)
|
|||||||
NANOEND
|
NANOEND
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void TextTail_SetLivingTime(long) { MT_PLATFORM_STUB(); }
|
|
||||||
namespace {
|
namespace {
|
||||||
// The supplied 40250 Client/locale.cfg selects "en" (code page 1252).
|
// The supplied 40250 Client/locale.cfg selects "en" (code page 1252).
|
||||||
// Keep these mutable for app.ForceSetLocale, as Locale.cpp does.
|
// Keep these mutable for app.ForceSetLocale, as Locale.cpp does.
|
||||||
|
|||||||
@@ -26,6 +26,41 @@
|
|||||||
// 40250 UserInterface.cpp:49.
|
// 40250 UserInterface.cpp:49.
|
||||||
bool __IS_TEST_SERVER_MODE__=false;
|
bool __IS_TEST_SERVER_MODE__=false;
|
||||||
|
|
||||||
|
// 40250 UserInterface.cpp:98. PORT: LoadString reads the executable's STRINGTABLE; the one the supplied English
|
||||||
|
// client resolves is UserInterface.rc's LANG_ENGLISH, SUBLANG_ENGLISH_US section (ids from resource.h).
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const char* LoadAppString(DWORD dwID)
|
||||||
|
{
|
||||||
|
switch (dwID)
|
||||||
|
{
|
||||||
|
case 1: return "Metin 2"; // IDS_APP_NAME
|
||||||
|
case 2: return "'s"; // IDS_POSSESSIVE_MORPHENE
|
||||||
|
case 3: return "IDS_WARN_BAD_DRIVER"; // IDS_WARN_BAD_DRIVER
|
||||||
|
case 4: return "IDS_WARN_NO_TNL"; // IDS_WARN_NO_TNL
|
||||||
|
case 5: return "Cannot read %s file"; // IDS_ERR_CANNOT_READ_FILE
|
||||||
|
case 6: return "File '%s' is not latest version. Please launch patcher."; // IDS_ERR_NOT_LATEST_FILE
|
||||||
|
case 7: return "Please run patcher."; // IDS_ERR_MUST_LAUNCH_FROM_PATCHER
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<DWORD, std::string> gs_kMap_dwID_stLocale;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
const std::string& ApplicationStringTable_GetString(DWORD dwID)
|
||||||
|
{
|
||||||
|
std::string& rstLocale=gs_kMap_dwID_stLocale[dwID];
|
||||||
|
rstLocale=LoadAppString(dwID);
|
||||||
|
|
||||||
|
return rstLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ApplicationStringTable_GetStringz(DWORD dwID)
|
||||||
|
{
|
||||||
|
return ApplicationStringTable_GetString(dwID).c_str();
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// Lowercased file name -> on-disk spelling, for the files directly in `folder`.
|
// Lowercased file name -> on-disk spelling, for the files directly in `folder`.
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
// Stand-in for the 40250 logic unit UserInterface/PythonTextTail.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/PythonTextTail.h"
|
|
||||||
|
|
||||||
#include "../../PlatformStub.h"
|
|
||||||
|
|
||||||
CPythonTextTail::CPythonTextTail()
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
CPythonTextTail::~CPythonTextTail()
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CPythonTextTail::RegisterChatTail(DWORD, const char *) -> void
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CPythonTextTail::RegisterCharacterTextTail(DWORD, DWORD, const D3DXCOLOR &, float) -> void
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CPythonTextTail::SetCharacterTextTailColor(DWORD, const D3DXCOLOR &) -> void
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CPythonTextTail::DeleteCharacterTextTail(DWORD) -> void
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CPythonTextTail::AttachTitle(DWORD, const char *, const D3DXCOLOR &) -> void
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CPythonTextTail::DetachTitle(DWORD) -> void
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CPythonTextTail::AttachLevel(DWORD, const char *, const D3DXCOLOR &) -> void
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CPythonTextTail::RegisterItemTextTail(DWORD, const char *, CGraphicObjectInstance *) -> void
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CPythonTextTail::DeleteItemTextTail(DWORD) -> void
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CPythonTextTail::SetItemTextTailOwner(DWORD, const char *) -> void
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 40250 returns -1 when no item text tail is under the mouse; RegisterItemTextTail is still a stub, so
|
|
||||||
// m_ItemTextTailMap stays empty and that is always the answer (0 would pick ground item VID 0).
|
|
||||||
auto CPythonTextTail::Pick(int, int) -> int
|
|
||||||
{
|
|
||||||
MT_PLATFORM_STUB();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,235 @@
|
|||||||
|
#include "StdAfx.h"
|
||||||
|
#include "PythonTextTail.h"
|
||||||
|
#include "PythonCharacterManager.h"
|
||||||
|
|
||||||
|
PyObject * textTailClear(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
CPythonTextTail::Instance().Clear();
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailUpdateAllTextTail(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
CPythonTextTail::Instance().UpdateAllTextTail();
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailUpdateShowingTextTail(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
CPythonTextTail::Instance().UpdateShowingTextTail();
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailRender(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
CPythonTextTail::Instance().Render();
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailRegisterCharacterTextTail(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int iGuildID;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &iGuildID))
|
||||||
|
return Py_BuildException();
|
||||||
|
int iVirtualID;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 1, &iVirtualID))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
CPythonTextTail::Instance().RegisterCharacterTextTail(iGuildID, iVirtualID, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailGetPosition(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int VirtualID;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
float x=0.0f;
|
||||||
|
float y=0.0f;
|
||||||
|
float z=0.0f;
|
||||||
|
bool isData=CPythonTextTail::Instance().GetTextTailPosition(VirtualID, &x, &y, &z);
|
||||||
|
if (!isData)
|
||||||
|
{
|
||||||
|
CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance();
|
||||||
|
CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr();
|
||||||
|
if (pkInstMain)
|
||||||
|
{
|
||||||
|
const D3DXVECTOR3 & c_rv3Position = pkInstMain->GetGraphicThingInstanceRef().GetPosition();
|
||||||
|
CPythonGraphic::Instance().ProjectPosition(c_rv3Position.x, c_rv3Position.y, c_rv3Position.z, &x, &y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Py_BuildValue("fff", x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailIsChat(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int VirtualID;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
return Py_BuildValue("i", CPythonTextTail::Instance().IsChatTextTail(VirtualID));
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailRegisterChatTail(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int VirtualID;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
char * szText;
|
||||||
|
if (!PyTuple_GetString(poArgs, 1, &szText))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
CPythonTextTail::Instance().RegisterChatTail(VirtualID, szText);
|
||||||
|
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailRegisterInfoTail(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int VirtualID;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
char * szText;
|
||||||
|
if (!PyTuple_GetString(poArgs, 1, &szText))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
CPythonTextTail::Instance().RegisterInfoTail(VirtualID, szText);
|
||||||
|
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailAttachTitle(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int iVirtualID;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID))
|
||||||
|
return Py_BuildException();
|
||||||
|
char * szName;
|
||||||
|
if (!PyTuple_GetString(poArgs, 1, &szName))
|
||||||
|
return Py_BuildException();
|
||||||
|
float fr;
|
||||||
|
if (!PyTuple_GetFloat(poArgs, 2, &fr))
|
||||||
|
return Py_BuildException();
|
||||||
|
float fg;
|
||||||
|
if (!PyTuple_GetFloat(poArgs, 3, &fg))
|
||||||
|
return Py_BuildException();
|
||||||
|
float fb;
|
||||||
|
if (!PyTuple_GetFloat(poArgs, 4, &fb))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
CPythonTextTail::Instance().AttachTitle(iVirtualID, szName, D3DXCOLOR(fr, fg, fb, 1.0f));
|
||||||
|
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailShowCharacterTextTail(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int VirtualID;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
CPythonTextTail::Instance().ShowCharacterTextTail(VirtualID);
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailShowItemTextTail(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int VirtualID;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &VirtualID))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
CPythonTextTail::Instance().ShowItemTextTail(VirtualID);
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailArrangeTextTail(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
CPythonTextTail::Instance().ArrangeTextTail();
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailHideAllTextTail(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
CPythonTextTail::Instance().HideAllTextTail();
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailShowAllTextTail(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
CPythonTextTail::Instance().ShowAllTextTail();
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailPick(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int ix;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &ix))
|
||||||
|
return Py_BuildException();
|
||||||
|
int iy;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 1, &iy))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
int iValue = CPythonTextTail::Instance().Pick(ix, iy);
|
||||||
|
return Py_BuildValue("i", iValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailSelectItemName(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int iVirtualID;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
CPythonTextTail::Instance().SelectItemName(iVirtualID);
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * textTailEnablePKTitle(PyObject * poSelf, PyObject * poArgs)
|
||||||
|
{
|
||||||
|
int iFlag;
|
||||||
|
if (!PyTuple_GetInteger(poArgs, 0, &iFlag))
|
||||||
|
return Py_BuildException();
|
||||||
|
|
||||||
|
CPythonTextTail::Instance().EnablePKTitle(iFlag);
|
||||||
|
return Py_BuildNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initTextTail()
|
||||||
|
{
|
||||||
|
static PyMethodDef s_methods[] =
|
||||||
|
{
|
||||||
|
{ "Clear", textTailClear, METH_VARARGS },
|
||||||
|
|
||||||
|
{ "UpdateAllTextTail", textTailUpdateAllTextTail, METH_VARARGS },
|
||||||
|
{ "UpdateShowingTextTail", textTailUpdateShowingTextTail, METH_VARARGS },
|
||||||
|
{ "Render", textTailRender, METH_VARARGS },
|
||||||
|
|
||||||
|
{ "ShowCharacterTextTail", textTailShowCharacterTextTail, METH_VARARGS },
|
||||||
|
{ "ShowItemTextTail", textTailShowItemTextTail, METH_VARARGS },
|
||||||
|
|
||||||
|
{ "GetPosition", textTailGetPosition, METH_VARARGS },
|
||||||
|
{ "IsChat", textTailIsChat, METH_VARARGS },
|
||||||
|
|
||||||
|
{ "ArrangeTextTail", textTailArrangeTextTail, METH_VARARGS },
|
||||||
|
{ "HideAllTextTail", textTailHideAllTextTail, METH_VARARGS },
|
||||||
|
{ "ShowAllTextTail", textTailShowAllTextTail, METH_VARARGS },
|
||||||
|
|
||||||
|
{ "Pick", textTailPick, METH_VARARGS },
|
||||||
|
{ "SelectItemName", textTailSelectItemName, METH_VARARGS },
|
||||||
|
|
||||||
|
{ "EnablePKTitle", textTailEnablePKTitle, METH_VARARGS },
|
||||||
|
|
||||||
|
// For Test
|
||||||
|
{ "RegisterCharacterTextTail", textTailRegisterCharacterTextTail, METH_VARARGS },
|
||||||
|
{ "RegisterChatTail", textTailRegisterChatTail, METH_VARARGS },
|
||||||
|
{ "RegisterInfoTail", textTailRegisterInfoTail, METH_VARARGS },
|
||||||
|
{ "AttachTitle", textTailAttachTitle, METH_VARARGS },
|
||||||
|
|
||||||
|
{ NULL, NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
Py_InitModule("textTail", s_methods);
|
||||||
|
}
|
||||||
@@ -50,8 +50,15 @@ void initPlayer();
|
|||||||
void initItem();
|
void initItem();
|
||||||
void initNonPlayer();
|
void initNonPlayer();
|
||||||
void initTrade();
|
void initTrade();
|
||||||
|
void initTextTail();
|
||||||
void initChat();
|
void initChat();
|
||||||
void initnet();
|
void initnet();
|
||||||
void initeffect();
|
void initeffect();
|
||||||
void initfly();
|
void initfly();
|
||||||
void initServerStateChecker();
|
void initServerStateChecker();
|
||||||
|
|
||||||
|
extern const std::string& ApplicationStringTable_GetString(DWORD dwID);
|
||||||
|
extern const std::string& ApplicationStringTable_GetString(DWORD dwID, LPCSTR szKey);
|
||||||
|
|
||||||
|
extern const char* ApplicationStringTable_GetStringz(DWORD dwID);
|
||||||
|
extern const char* ApplicationStringTable_GetStringz(DWORD dwID, LPCSTR szKey);
|
||||||
|
|||||||
@@ -101,6 +101,45 @@ D3DXVECTOR3* D3DXVec3TransformCoord(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, co
|
|||||||
return pOut;
|
return pOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// World * View * Projection, skipping the null ones.
|
||||||
|
D3DXMATRIX world_view_projection(const D3DXMATRIX* pProjection, const D3DXMATRIX* pView, const D3DXMATRIX* pWorld)
|
||||||
|
{
|
||||||
|
D3DXMATRIX m;
|
||||||
|
D3DXMatrixIdentity(&m);
|
||||||
|
for (const D3DXMATRIX* p : {pWorld, pView, pProjection})
|
||||||
|
if (p)
|
||||||
|
D3DXMatrixMultiply(&m, &m, p);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
D3DXVECTOR3* D3DXVec3Project(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DVIEWPORT8* pViewport,
|
||||||
|
const D3DXMATRIX* pProjection, const D3DXMATRIX* pView, const D3DXMATRIX* pWorld)
|
||||||
|
{
|
||||||
|
const D3DXMATRIX m = world_view_projection(pProjection, pView, pWorld);
|
||||||
|
D3DXVECTOR3 v;
|
||||||
|
D3DXVec3TransformCoord(&v, pV, &m);
|
||||||
|
pOut->x = pViewport->X + (1.0f + v.x) * pViewport->Width / 2.0f;
|
||||||
|
pOut->y = pViewport->Y + (1.0f - v.y) * pViewport->Height / 2.0f;
|
||||||
|
pOut->z = pViewport->MinZ + v.z * (pViewport->MaxZ - pViewport->MinZ);
|
||||||
|
return pOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DXVECTOR3* D3DXVec3Unproject(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DVIEWPORT8* pViewport,
|
||||||
|
const D3DXMATRIX* pProjection, const D3DXMATRIX* pView, const D3DXMATRIX* pWorld)
|
||||||
|
{
|
||||||
|
D3DXMATRIX m = world_view_projection(pProjection, pView, pWorld);
|
||||||
|
D3DXMatrixInverse(&m, nullptr, &m);
|
||||||
|
D3DXVECTOR3 v;
|
||||||
|
v.x = 2.0f * (pV->x - pViewport->X) / pViewport->Width - 1.0f;
|
||||||
|
v.y = 1.0f - 2.0f * (pV->y - pViewport->Y) / pViewport->Height;
|
||||||
|
v.z = (pV->z - pViewport->MinZ) / (pViewport->MaxZ - pViewport->MinZ);
|
||||||
|
D3DXVec3TransformCoord(pOut, &v, &m);
|
||||||
|
return pOut;
|
||||||
|
}
|
||||||
|
|
||||||
D3DXVECTOR3* D3DXVec3TransformNormal(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM)
|
D3DXVECTOR3* D3DXVec3TransformNormal(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM)
|
||||||
{
|
{
|
||||||
D3DXVECTOR3 out;
|
D3DXVECTOR3 out;
|
||||||
|
|||||||
@@ -337,6 +337,11 @@ D3DXVECTOR4* D3DXVec3Transform(D3DXVECTOR4* pOut, const D3DXVECTOR3* pV, const D
|
|||||||
D3DXVECTOR3* D3DXVec3TransformCoord(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM);
|
D3DXVECTOR3* D3DXVec3TransformCoord(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM);
|
||||||
D3DXVECTOR3* D3DXVec3TransformNormal(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM);
|
D3DXVECTOR3* D3DXVec3TransformNormal(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM);
|
||||||
D3DXVECTOR4* D3DXVec4Transform(D3DXVECTOR4* pOut, const D3DXVECTOR4* pV, const D3DXMATRIX* pM);
|
D3DXVECTOR4* D3DXVec4Transform(D3DXVECTOR4* pOut, const D3DXVECTOR4* pV, const D3DXMATRIX* pM);
|
||||||
|
// D3DX semantics: object space → viewport pixels (x, y) and depth in [MinZ, MaxZ], and back; a null matrix is identity.
|
||||||
|
D3DXVECTOR3* D3DXVec3Project(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DVIEWPORT8* pViewport,
|
||||||
|
const D3DXMATRIX* pProjection, const D3DXMATRIX* pView, const D3DXMATRIX* pWorld);
|
||||||
|
D3DXVECTOR3* D3DXVec3Unproject(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DVIEWPORT8* pViewport,
|
||||||
|
const D3DXMATRIX* pProjection, const D3DXMATRIX* pView, const D3DXMATRIX* pWorld);
|
||||||
|
|
||||||
// --- D3DXMATRIX ---
|
// --- D3DXMATRIX ---
|
||||||
inline D3DXMATRIX* D3DXMatrixIdentity(D3DXMATRIX* pOut)
|
inline D3DXMATRIX* D3DXMatrixIdentity(D3DXMATRIX* pOut)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
#include "UserInterface/PythonItem.h"
|
#include "UserInterface/PythonItem.h"
|
||||||
#include "UserInterface/StdAfx.h"
|
#include "UserInterface/StdAfx.h"
|
||||||
#include "UserInterface/PythonExchange.h"
|
#include "UserInterface/PythonExchange.h"
|
||||||
|
#include "UserInterface/PythonTextTail.h"
|
||||||
#include "UserInterface/PythonCharacterManager.h"
|
#include "UserInterface/PythonCharacterManager.h"
|
||||||
#include "UserInterface/InstanceBase.h"
|
#include "UserInterface/InstanceBase.h"
|
||||||
#include "UserInterface/PythonBackground.h"
|
#include "UserInterface/PythonBackground.h"
|
||||||
@@ -513,10 +514,34 @@ int main(int argc, char** argv)
|
|||||||
std::string(owner) == FakeLoginServer::kCharacterName);
|
std::string(owner) == FakeLoginServer::kCharacterName);
|
||||||
CHECK(ground.GetVirtualNumberOfGroundItem(FakeLoginServer::kGroundItemVID) == FakeLoginServer::kGroundItemVnum);
|
CHECK(ground.GetVirtualNumberOfGroundItem(FakeLoginServer::kGroundItemVID) == FakeLoginServer::kGroundItemVnum);
|
||||||
std::printf("port_login_flow_test: ground item at %.0f %.0f\n", item_pos.x, item_pos.y);
|
std::printf("port_login_flow_test: ground item at %.0f %.0f\n", item_pos.x, item_pos.y);
|
||||||
|
// CPythonItem::CreateItem registered the item's name tail (CPythonTextTail::RegisterItemTextTail) next to
|
||||||
|
// the actor's character tail. Shown and projected, the name is pickable on screen: textTail.Pick is how
|
||||||
|
// game.GameWindow.OnRender finds the item under the cursor while names are shown.
|
||||||
|
auto tail_info = [] {
|
||||||
|
std::string info;
|
||||||
|
CPythonTextTail::Instance().GetInfo(&info);
|
||||||
|
return info;
|
||||||
|
};
|
||||||
|
std::printf("port_login_flow_test: %s\n", tail_info().c_str());
|
||||||
|
CHECK(tail_info().find("ItemTail (Map 1,") != std::string::npos);
|
||||||
|
CHECK(tail_info().find("ChrTail (Map 1,") != std::string::npos);
|
||||||
|
// Holding ALT (game.GameWindow.ShowName) makes OnRender show every tail in range and project it after
|
||||||
|
// app.RenderGame; the item tail keeps that screen rect, which is what textTail.Pick tests.
|
||||||
|
PythonBoot::UIKey(DIK_LMENU, true);
|
||||||
|
pump_until(0.1, [] { return false; });
|
||||||
|
PythonBoot::UIKey(DIK_LMENU, false);
|
||||||
|
int picked = -1, pick_x = 0, pick_y = 0;
|
||||||
|
for (int y = 0; y < 1200 && picked < 0; y += 2)
|
||||||
|
for (int x = 0; x < 1600 && picked < 0; x += 2)
|
||||||
|
if ((picked = CPythonTextTail::Instance().Pick(x, y)) >= 0)
|
||||||
|
pick_x = x, pick_y = y;
|
||||||
|
std::printf("port_login_flow_test: item name tail picked at %d %d\n", pick_x, pick_y);
|
||||||
|
CHECK(picked == (int) FakeLoginServer::kGroundItemVID);
|
||||||
CHECK(py("import player\nplayer.PickCloseItem()"));
|
CHECK(py("import player\nplayer.PickCloseItem()"));
|
||||||
const std::string pickup = "game2:pickup " + std::to_string(FakeLoginServer::kGroundItemVID);
|
const std::string pickup = "game2:pickup " + std::to_string(FakeLoginServer::kGroundItemVID);
|
||||||
CHECK(pump_until(2, [&] { return server->Has(pickup); }));
|
CHECK(pump_until(2, [&] { return server->Has(pickup); }));
|
||||||
CHECK(pump_until(2, [&] { return !ground.GetGroundItemPosition(FakeLoginServer::kGroundItemVID, &item_pos); }));
|
CHECK(pump_until(2, [&] { return !ground.GetGroundItemPosition(FakeLoginServer::kGroundItemVID, &item_pos); }));
|
||||||
|
CHECK(tail_info().find("ItemTail (Map 0,") != std::string::npos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exchange (CPythonExchange + exchange module): net.SendExchangeStartPacket → the fake partner's GC_EXCHANGE
|
// Exchange (CPythonExchange + exchange module): net.SendExchangeStartPacket → the fake partner's GC_EXCHANGE
|
||||||
|
|||||||
Reference in New Issue
Block a user