diff --git a/audit/history.jsonl b/audit/history.jsonl index d49c7379..627d4774 100644 --- a/audit/history.jsonl +++ b/audit/history.jsonl @@ -534,3 +534,4 @@ {"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-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"]} +{"time": "2026-09-24T10:00:00Z", "event": "port_round", "unit": "PORT-PLAN batch 2 P3-e: PythonMiniMap + miniMap module", "ported": ["UserInterface/PythonMiniMap.cpp", "UserInterface/PythonMiniMapModule.cpp", "PRTerrainLib/StdAfx.cpp"], "adapted": [], "divergent": ["GameLib/MapManager.cpp:CMapManager::IsMapOutdoor (false until CMapOutdoor is ported)"], "needs_live": [], "tests": ["port.login_flow: miniMap.isShow() after uiminimap, GetAtlasSize() not loaded", "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": ["CMapOutdoor (minimap terrain textures, atlas)", "CEffectManager", "CPythonSkill"]} diff --git a/audit/port-map/GameLib/MapManager.cpp.json b/audit/port-map/GameLib/MapManager.cpp.json index 1a84d589..95d2aa85 100644 --- a/audit/port-map/GameLib/MapManager.cpp.json +++ b/audit/port-map/GameLib/MapManager.cpp.json @@ -5,7 +5,12 @@ "contracts": [], "functions": { "CMapManager::IsMapOutdoor": { - "status": "TODO" + "status": "DIVERGENT", + "impl": [ + "extension/src/platform/pending/GameLib/MapManager.cpp:CMapManager::IsMapOutdoor" + ], + "note": "Returns false on every map: CMapOutdoor is not ported (the Godot terrain adapter draws the map), so CPythonMiniMap Update/Render/LoadAtlas take their no-outdoor-map path: no minimap terrain textures, marks or atlas. Resolves when CMapOutdoor is ported.", + "test": "extension/tests/port_login_flow_test.cpp miniMap step (miniMap.GetAtlasSize() reports not loaded)" }, "CMapManager::GetMapOutdoorRef": { "status": "TODO" diff --git a/audit/port-map/UserInterface/PythonMiniMap.cpp.json b/audit/port-map/UserInterface/PythonMiniMap.cpp.json new file mode 100644 index 00000000..fc631d44 --- /dev/null +++ b/audit/port-map/UserInterface/PythonMiniMap.cpp.json @@ -0,0 +1,320 @@ +{ + "reference": "UserInterface/PythonMiniMap.cpp", + "reference_sha256": "bc931ed36fd90f631ee8c287cdf3816d58e9ee640511afc36ac2a684d69de738", + "priority": "P3", + "contracts": [], + "functions": { + "CPythonMiniMap::AddObserver": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::AddObserver" + ] + }, + "CPythonMiniMap::MoveObserver": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::MoveObserver" + ] + }, + "CPythonMiniMap::RemoveObserver": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::RemoveObserver" + ] + }, + "CPythonMiniMap::SetCenterPosition": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::SetCenterPosition" + ] + }, + "CPythonMiniMap::Update": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::Update" + ] + }, + "CPythonMiniMap::Render": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::Render" + ] + }, + "CPythonMiniMap::SetScale": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::SetScale" + ] + }, + "CPythonMiniMap::ScaleUp": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::ScaleUp" + ] + }, + "CPythonMiniMap::ScaleDown": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::ScaleDown" + ] + }, + "CPythonMiniMap::SetMiniMapSize": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::SetMiniMapSize" + ] + }, + "CPythonMiniMap::Create": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::Create" + ] + }, + "CPythonMiniMap::__SetPosition": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::__SetPosition" + ] + }, + "CPythonMiniMap::ClearAtlasMarkInfo": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::ClearAtlasMarkInfo" + ] + }, + "CPythonMiniMap::RegisterAtlasMark": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::RegisterAtlasMark" + ] + }, + "CPythonMiniMap::ClearGuildArea": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::ClearGuildArea" + ] + }, + "CPythonMiniMap::RegisterGuildArea": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::RegisterGuildArea" + ] + }, + "CPythonMiniMap::GetGuildAreaID": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::GetGuildAreaID" + ] + }, + "CPythonMiniMap::CreateTarget": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::CreateTarget" + ] + }, + "CPythonMiniMap::UpdateTarget": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::UpdateTarget" + ] + }, + "CPythonMiniMap::DeleteTarget": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::DeleteTarget" + ] + }, + "CPythonMiniMap::__LoadAtlasMarkInfo": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::__LoadAtlasMarkInfo" + ] + }, + "CPythonMiniMap::LoadAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::LoadAtlas" + ] + }, + "CPythonMiniMap::__GlobalPositionToAtlasPosition": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::__GlobalPositionToAtlasPosition" + ] + }, + "CPythonMiniMap::UpdateAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::UpdateAtlas" + ] + }, + "CPythonMiniMap::RenderAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::RenderAtlas" + ] + }, + "CPythonMiniMap::GetPickedInstanceInfo": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::GetPickedInstanceInfo" + ] + }, + "CPythonMiniMap::GetAtlasInfo": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::GetAtlasInfo" + ] + }, + "CPythonMiniMap::GetAtlasSize": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::GetAtlasSize" + ] + }, + "CPythonMiniMap::AddWayPoint": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::AddWayPoint" + ] + }, + "CPythonMiniMap::RemoveWayPoint": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::RemoveWayPoint" + ] + }, + "CPythonMiniMap::__GetWayPoint": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::__GetWayPoint" + ] + }, + "CPythonMiniMap::__UpdateWayPoint": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::__UpdateWayPoint" + ] + }, + "CPythonMiniMap::__RenderWayPointMark": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::__RenderWayPointMark" + ] + }, + "CPythonMiniMap::__RenderMiniWayPointMark": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::__RenderMiniWayPointMark" + ] + }, + "CPythonMiniMap::__RenderTargetMark": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::__RenderTargetMark" + ] + }, + "CPythonMiniMap::AddSignalPoint": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::AddSignalPoint" + ] + }, + "CPythonMiniMap::ClearAllSignalPoint": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::ClearAllSignalPoint" + ] + }, + "CPythonMiniMap::RegisterAtlasWindow": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::RegisterAtlasWindow" + ] + }, + "CPythonMiniMap::UnregisterAtlasWindow": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::UnregisterAtlasWindow" + ] + }, + "CPythonMiniMap::OpenAtlasWindow": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::OpenAtlasWindow" + ] + }, + "CPythonMiniMap::SetAtlasCenterPosition": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::SetAtlasCenterPosition" + ] + }, + "CPythonMiniMap::IsAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::IsAtlas" + ] + }, + "CPythonMiniMap::ShowAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::ShowAtlas" + ] + }, + "CPythonMiniMap::HideAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::HideAtlas" + ] + }, + "CPythonMiniMap::CanShowAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::CanShowAtlas" + ] + }, + "CPythonMiniMap::CanShow": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::CanShow" + ] + }, + "CPythonMiniMap::Show": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::Show" + ] + }, + "CPythonMiniMap::Hide": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::Hide" + ] + }, + "CPythonMiniMap::__Initialize": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::__Initialize" + ] + }, + "CPythonMiniMap::Destroy": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::Destroy" + ] + }, + "CPythonMiniMap::CPythonMiniMap": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::CPythonMiniMap" + ] + }, + "CPythonMiniMap::~CPythonMiniMap": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMap.cpp:CPythonMiniMap::~CPythonMiniMap" + ] + } + } +} diff --git a/audit/port-map/UserInterface/PythonMiniMapModule.cpp.json b/audit/port-map/UserInterface/PythonMiniMapModule.cpp.json new file mode 100644 index 00000000..d5cc87d6 --- /dev/null +++ b/audit/port-map/UserInterface/PythonMiniMapModule.cpp.json @@ -0,0 +1,176 @@ +{ + "reference": "UserInterface/PythonMiniMapModule.cpp", + "reference_sha256": "49293a3eacbb0118f611968a2f6f635cdba66a7db63630330768006d007a6c32", + "priority": "P4", + "contracts": [], + "functions": { + "miniMapSetScale": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapSetScale" + ] + }, + "miniMapSetCenterPosition": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapSetCenterPosition" + ] + }, + "miniMapSetMiniMapSize": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapSetMiniMapSize" + ] + }, + "miniMapDestroy": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapDestroy" + ] + }, + "miniMapCreate": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapCreate" + ] + }, + "miniMapUpdate": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapUpdate" + ] + }, + "miniMapRender": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapRender" + ] + }, + "miniMapShow": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapShow" + ] + }, + "miniMapHide": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapHide" + ] + }, + "miniMapisShow": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapisShow" + ] + }, + "miniMapScaleUp": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapScaleUp" + ] + }, + "miniMapScaleDown": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapScaleDown" + ] + }, + "miniMapGetInfo": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapGetInfo" + ] + }, + "miniMapLoadAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapLoadAtlas" + ] + }, + "miniMapUpdateAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapUpdateAtlas" + ] + }, + "miniMapRenderAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapRenderAtlas" + ] + }, + "miniMapShowAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapShowAtlas" + ] + }, + "miniMapHideAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapHideAtlas" + ] + }, + "miniMapisShowAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapisShowAtlas" + ] + }, + "miniMapIsAtlas": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapIsAtlas" + ] + }, + "miniMapGetAtlasInfo": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapGetAtlasInfo" + ] + }, + "miniMapGetAtlasSize": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapGetAtlasSize" + ] + }, + "miniMapAddWayPoint": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapAddWayPoint" + ] + }, + "miniMapRemoveWayPoint": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapRemoveWayPoint" + ] + }, + "miniMapRegisterAtlasWindow": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapRegisterAtlasWindow" + ] + }, + "miniMapUnregisterAtlasWindow": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapUnregisterAtlasWindow" + ] + }, + "miniMapGetGuildAreaID": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:miniMapGetGuildAreaID" + ] + }, + "initMiniMap": { + "status": "PORTED", + "impl": [ + "extension/src/port/UserInterface/PythonMiniMapModule.cpp:initMiniMap" + ] + } + } +} diff --git a/docs/PORT-PLAN.md b/docs/PORT-PLAN.md index faebcae5..8649d289 100644 --- a/docs/PORT-PLAN.md +++ b/docs/PORT-PLAN.md @@ -442,6 +442,8 @@ extension/third_party/cpython-2.7.18/ # 静态库(2P 批次 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`。 + P3-e(2026-09-24):`PythonMiniMap.cpp` 与 `PythonMiniMapModule.cpp` 原样移植(无手改),删除 pending 替身与 miniMap 模块桩,`initMiniMap()` 按 40250 顺序在 `initnet()` 之后;`PRTerrainLib/StdAfx.cpp`(`PR_FCNV/PR_ICNV`)原样复制,UserInterface PCH 按 40250 补 `PRTerrainLib/StdAfx.h`,`TerrainType.h` 的 `PR_FLOAT_TO_INTASM` 在非 MSVC 下用 `lrintf`(x87 fistp 默认舍入)代替内联汇编;`D3DXMath.h` 补 `D3DXColorModulate`。缺口:`CMapOutdoor` 未移植(地形由 Godot 适配层绘制),pending `CMapManager::IsMapOutdoor()` 返回 false(记 DIVERGENT),`GetMapOutdoorRef` 与 pending `CMapOutdoor::GetTerrainPointer/GetBaseXY` 只为链接存在、不可达——小地图地形贴图、标记与大地图(atlas)因此走 40250「非室外地图」路径不显示,待 `CMapOutdoor` 移植后自然恢复。`port.login_flow` 验证 uiminimap 创建并显示 miniMap、`GetAtlasSize()` 报未载入。P3 物品链与三个 UI 单元至此完成;下一步候选:`CMapOutdoor`(解锁小地图/大地图)、`CEffectManager`/EffectLib、`CPythonSkill`。 + 每个切片都必须同时跑 legacy/port 双路回归;只有 2V3 稳定并把默认路由切到 `port` 后,才能删除总开关和剩余 legacy 宿主。 ## 5. 数据源切换:m2dev assets → 40250 diff --git a/extension/src/platform/ScriptLib/GameplayModuleConstants.cpp b/extension/src/platform/ScriptLib/GameplayModuleConstants.cpp index f61e8727..c3f35326 100644 --- a/extension/src/platform/ScriptLib/GameplayModuleConstants.cpp +++ b/extension/src/platform/ScriptLib/GameplayModuleConstants.cpp @@ -104,21 +104,6 @@ void AddStubConstants_messenger(PyObject* poModule) (void) poModule; } -// 40250 UserInterface/PythonMiniMapModule.cpp -void AddStubConstants_miniMap(PyObject* poModule) -{ - (void) poModule; - PyModule_AddIntConstant(poModule, "TYPE_OPC", CPythonMiniMap::TYPE_OPC); - PyModule_AddIntConstant(poModule, "TYPE_OPCPVP", CPythonMiniMap::TYPE_OPCPVP); - PyModule_AddIntConstant(poModule, "TYPE_OPCPVPSELF", CPythonMiniMap::TYPE_OPCPVPSELF); - PyModule_AddIntConstant(poModule, "TYPE_NPC", CPythonMiniMap::TYPE_NPC); - PyModule_AddIntConstant(poModule, "TYPE_MONSTER", CPythonMiniMap::TYPE_MONSTER); - PyModule_AddIntConstant(poModule, "TYPE_WARP", CPythonMiniMap::TYPE_WARP); - PyModule_AddIntConstant(poModule, "TYPE_WAYPOINT", CPythonMiniMap::TYPE_WAYPOINT); - PyModule_AddIntConstant(poModule, "TYPE_PARTY", CPythonMiniMap::TYPE_PARTY); - PyModule_AddIntConstant(poModule, "TYPE_EMPIRE", CPythonMiniMap::TYPE_EMPIRE); -} - // 40250 UserInterface/PythonProfilerModule.cpp void AddStubConstants_profiler(PyObject* poModule) { diff --git a/extension/src/platform/ScriptLib/GameplayModules.cpp b/extension/src/platform/ScriptLib/GameplayModules.cpp index dfe2e6dd..037a5711 100644 --- a/extension/src/platform/ScriptLib/GameplayModules.cpp +++ b/extension/src/platform/ScriptLib/GameplayModules.cpp @@ -11,7 +11,6 @@ void AddStubConstants_eventMgr(PyObject* poModule); void AddStubConstants_guild(PyObject* poModule); void AddStubConstants_ime(PyObject* poModule); void AddStubConstants_messenger(PyObject* poModule); -void AddStubConstants_miniMap(PyObject* poModule); void AddStubConstants_profiler(PyObject* poModule); void AddStubConstants_quest(PyObject* poModule); void AddStubConstants_safebox(PyObject* poModule); @@ -341,64 +340,6 @@ PyMethodDef methods_messenger[] = { { "SetMessengerHandler", stub_messenger_SetMessengerHandler, METH_VARARGS }, { NULL, NULL } }; -// 40250 UserInterface/PythonMiniMapModule.cpp: miniMap export names. -PyObject* stub_miniMap_SetScale(PyObject*, PyObject*) { return stub_call_named("miniMap.SetScale", Py_BuildNone()); } -PyObject* stub_miniMap_ScaleUp(PyObject*, PyObject*) { return stub_call_named("miniMap.ScaleUp", Py_BuildNone()); } -PyObject* stub_miniMap_ScaleDown(PyObject*, PyObject*) { return stub_call_named("miniMap.ScaleDown", Py_BuildNone()); } -PyObject* stub_miniMap_SetMiniMapSize(PyObject*, PyObject*) { return stub_call_named("miniMap.SetMiniMapSize", Py_BuildNone()); } -PyObject* stub_miniMap_SetCenterPosition(PyObject*, PyObject*) { return stub_call_named("miniMap.SetCenterPosition", Py_BuildNone()); } -PyObject* stub_miniMap_Destroy(PyObject*, PyObject*) { return stub_call_named("miniMap.Destroy", Py_BuildNone()); } -PyObject* stub_miniMap_Create(PyObject*, PyObject*) { return stub_call_named("miniMap.Create", Py_BuildNone()); } -PyObject* stub_miniMap_Update(PyObject*, PyObject*) { return stub_call_named("miniMap.Update", Py_BuildNone()); } -PyObject* stub_miniMap_Render(PyObject*, PyObject*) { return stub_call_named("miniMap.Render", Py_BuildNone()); } -PyObject* stub_miniMap_Show(PyObject*, PyObject*) { return stub_call_named("miniMap.Show", Py_BuildNone()); } -PyObject* stub_miniMap_Hide(PyObject*, PyObject*) { return stub_call_named("miniMap.Hide", Py_BuildNone()); } -PyObject* stub_miniMap_isShow(PyObject*, PyObject*) { return stub_call_named("miniMap.isShow", Py_BuildValue("b", 0)); } -PyObject* stub_miniMap_GetInfo(PyObject*, PyObject*) { return stub_call_named("miniMap.GetInfo", Py_BuildValue("isiil", 0, "", 0, 0, 0L)); } -PyObject* stub_miniMap_LoadAtlas(PyObject*, PyObject*) { return stub_call_named("miniMap.LoadAtlas", Py_BuildNone()); } -PyObject* stub_miniMap_UpdateAtlas(PyObject*, PyObject*) { return stub_call_named("miniMap.UpdateAtlas", Py_BuildNone()); } -PyObject* stub_miniMap_RenderAtlas(PyObject*, PyObject*) { return stub_call_named("miniMap.RenderAtlas", Py_BuildNone()); } -PyObject* stub_miniMap_ShowAtlas(PyObject*, PyObject*) { return stub_call_named("miniMap.ShowAtlas", Py_BuildNone()); } -PyObject* stub_miniMap_HideAtlas(PyObject*, PyObject*) { return stub_call_named("miniMap.HideAtlas", Py_BuildNone()); } -PyObject* stub_miniMap_isShowAtlas(PyObject*, PyObject*) { return stub_call_named("miniMap.isShowAtlas", Py_BuildValue("b", 0)); } -PyObject* stub_miniMap_IsAtlas(PyObject*, PyObject*) { return stub_call_named("miniMap.IsAtlas", Py_BuildValue("b", 0)); } -PyObject* stub_miniMap_GetAtlasInfo(PyObject*, PyObject*) { return stub_call_named("miniMap.GetAtlasInfo", Py_BuildValue("isiili", 0, "", 0, 0, 0L, 0)); } -PyObject* stub_miniMap_GetAtlasSize(PyObject*, PyObject*) { return stub_call_named("miniMap.GetAtlasSize", Py_BuildValue("bii", 0, 0, 0)); } -PyObject* stub_miniMap_AddWayPoint(PyObject*, PyObject*) { return stub_call_named("miniMap.AddWayPoint", Py_BuildNone()); } -PyObject* stub_miniMap_RemoveWayPoint(PyObject*, PyObject*) { return stub_call_named("miniMap.RemoveWayPoint", Py_BuildNone()); } -PyObject* stub_miniMap_RegisterAtlasWindow(PyObject*, PyObject*) { return stub_call_named("miniMap.RegisterAtlasWindow", Py_BuildNone()); } -PyObject* stub_miniMap_UnregisterAtlasWindow(PyObject*, PyObject*) { return stub_call_named("miniMap.UnregisterAtlasWindow", Py_BuildNone()); } -PyObject* stub_miniMap_GetGuildAreaID(PyObject*, PyObject*) { return stub_call_named("miniMap.GetGuildAreaID", Py_BuildValue("i", 0)); } -PyMethodDef methods_miniMap[] = { - { "SetScale", stub_miniMap_SetScale, METH_VARARGS }, - { "ScaleUp", stub_miniMap_ScaleUp, METH_VARARGS }, - { "ScaleDown", stub_miniMap_ScaleDown, METH_VARARGS }, - { "SetMiniMapSize", stub_miniMap_SetMiniMapSize, METH_VARARGS }, - { "SetCenterPosition", stub_miniMap_SetCenterPosition, METH_VARARGS }, - { "Destroy", stub_miniMap_Destroy, METH_VARARGS }, - { "Create", stub_miniMap_Create, METH_VARARGS }, - { "Update", stub_miniMap_Update, METH_VARARGS }, - { "Render", stub_miniMap_Render, METH_VARARGS }, - { "Show", stub_miniMap_Show, METH_VARARGS }, - { "Hide", stub_miniMap_Hide, METH_VARARGS }, - { "isShow", stub_miniMap_isShow, METH_VARARGS }, - { "GetInfo", stub_miniMap_GetInfo, METH_VARARGS }, - { "LoadAtlas", stub_miniMap_LoadAtlas, METH_VARARGS }, - { "UpdateAtlas", stub_miniMap_UpdateAtlas, METH_VARARGS }, - { "RenderAtlas", stub_miniMap_RenderAtlas, METH_VARARGS }, - { "ShowAtlas", stub_miniMap_ShowAtlas, METH_VARARGS }, - { "HideAtlas", stub_miniMap_HideAtlas, METH_VARARGS }, - { "isShowAtlas", stub_miniMap_isShowAtlas, METH_VARARGS }, - { "IsAtlas", stub_miniMap_IsAtlas, METH_VARARGS }, - { "GetAtlasInfo", stub_miniMap_GetAtlasInfo, METH_VARARGS }, - { "GetAtlasSize", stub_miniMap_GetAtlasSize, METH_VARARGS }, - { "AddWayPoint", stub_miniMap_AddWayPoint, METH_VARARGS }, - { "RemoveWayPoint", stub_miniMap_RemoveWayPoint, METH_VARARGS }, - { "RegisterAtlasWindow", stub_miniMap_RegisterAtlasWindow, METH_VARARGS }, - { "UnregisterAtlasWindow", stub_miniMap_UnregisterAtlasWindow, METH_VARARGS }, - { "GetGuildAreaID", stub_miniMap_GetGuildAreaID, METH_VARARGS }, - { NULL, NULL } -}; // 40250 UserInterface/PythonProfilerModule.cpp: profiler export names. PyObject* stub_profiler_Push(PyObject*, PyObject*) { return stub_call_named("profiler.Push", Py_BuildNone()); } PyObject* stub_profiler_Pop(PyObject*, PyObject*) { return stub_call_named("profiler.Pop", Py_BuildNone()); } @@ -731,11 +672,6 @@ void init_2v0_gameplay_stubs() { PyModule_AddIntConstant(module, "__port_stub__", 1); AddStubConstants_messenger(module); } - { - PyObject* module = Py_InitModule("miniMap", methods_miniMap); - PyModule_AddIntConstant(module, "__port_stub__", 1); - AddStubConstants_miniMap(module); - } { PyObject* module = Py_InitModule("profiler", methods_profiler); PyModule_AddIntConstant(module, "__port_stub__", 1); diff --git a/extension/src/platform/ScriptLib/PythonBoot.cpp b/extension/src/platform/ScriptLib/PythonBoot.cpp index 92b8a8ab..4d524285 100644 --- a/extension/src/platform/ScriptLib/PythonBoot.cpp +++ b/extension/src/platform/ScriptLib/PythonBoot.cpp @@ -353,6 +353,7 @@ bool run_main_script_body(const char* lpCmdLine, std::string* error) initChat(); initTextTail(); initnet(); + initMiniMap(); initeffect(); initfly(); initServerStateChecker(); diff --git a/extension/src/platform/pending/GameLib/MapManager.cpp b/extension/src/platform/pending/GameLib/MapManager.cpp index 78a7c5d6..98086133 100644 --- a/extension/src/platform/pending/GameLib/MapManager.cpp +++ b/extension/src/platform/pending/GameLib/MapManager.cpp @@ -343,3 +343,20 @@ bool CMapManager::IsMapReady() auto found = s_native_maps.find(this); return found != s_native_maps.end() && found->second.ready; } + +// 40250 MapManager.cpp: true when the current map is a CMapOutdoor. PORT: CMapOutdoor is not ported (the Godot +// terrain adapter draws the map), so there is no outdoor map object to hand out; false keeps the 40250 callers +// (CPythonMiniMap::Update/Render/LoadAtlas) on their "no outdoor map" path instead of reaching into one. +auto CMapManager::IsMapOutdoor() -> bool +{ + MT_PLATFORM_STUB(); + return false; +} + +auto CMapManager::GetMapOutdoorRef() -> CMapOutdoor & +{ + MT_PLATFORM_STUB(); + // Never constructed (CMapOutdoor's constructor is not ported either); unreachable while IsMapOutdoor() is false. + alignas(CMapOutdoor) static unsigned char storage[sizeof(CMapOutdoor)]; + return *reinterpret_cast(storage); +} diff --git a/extension/src/platform/pending/GameLib/MapOutdoor.cpp b/extension/src/platform/pending/GameLib/MapOutdoor.cpp new file mode 100644 index 00000000..d4a0d3e4 --- /dev/null +++ b/extension/src/platform/pending/GameLib/MapOutdoor.cpp @@ -0,0 +1,18 @@ +// Stand-in for the 40250 logic unit GameLib/MapOutdoor.cpp, not ported yet: the members the ported units +// reference, as platform_stub.py stubs. Only reached behind CMapManager::IsMapOutdoor(), which is false until +// CMapOutdoor is ported. Delete this file in the commit that ports the unit into port/ (docs/PORT-PLAN.md). +#include "GameLib/StdAfx.h" +#include "GameLib/MapOutdoor.h" + +#include "../../PlatformStub.h" + +auto CMapOutdoor::GetTerrainPointer(BYTE, CTerrain **) -> BOOL +{ + MT_PLATFORM_STUB(); + return FALSE; +} + +auto CMapOutdoor::GetBaseXY(DWORD *, DWORD *) -> void +{ + MT_PLATFORM_STUB(); +} diff --git a/extension/src/platform/pending/UserInterface/PythonMiniMap.cpp b/extension/src/platform/pending/UserInterface/PythonMiniMap.cpp deleted file mode 100644 index 03aa06c0..00000000 --- a/extension/src/platform/pending/UserInterface/PythonMiniMap.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Stand-in for the 40250 logic unit UserInterface/PythonMiniMap.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/PythonMiniMap.h" - -#include "../../PlatformStub.h" - -CPythonMiniMap::CPythonMiniMap() -{ - MT_PLATFORM_STUB(); -} - -CPythonMiniMap::~CPythonMiniMap() -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::AddObserver(DWORD, float, float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::MoveObserver(DWORD, float, float) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::RemoveObserver(DWORD) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::ClearAtlasMarkInfo() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::RegisterAtlasMark(BYTE, const char *, long, long) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::ClearGuildArea() -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::RegisterGuildArea(DWORD, DWORD, long, long, long, long) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::CreateTarget(int, const char *) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::CreateTarget(int, const char *, DWORD) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::UpdateTarget(int, int, int) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::DeleteTarget(int) -> void -{ - MT_PLATFORM_STUB(); -} - -auto CPythonMiniMap::GetGuildAreaID(DWORD, DWORD) -> DWORD -{ - MT_PLATFORM_STUB(); - return mt_platform_stub_return(); -} diff --git a/extension/src/port/PRTerrainLib/StdAfx.cpp b/extension/src/port/PRTerrainLib/StdAfx.cpp new file mode 100644 index 00000000..bdc7fe91 --- /dev/null +++ b/extension/src/port/PRTerrainLib/StdAfx.cpp @@ -0,0 +1,10 @@ +// stdafx.cpp : source file that includes just the standard includes +// PRTerrainLib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "StdAfx.h" + +/* Fast Float<->Integer conversion */ +float PR_FCNV; +long PR_ICNV; + diff --git a/extension/src/port/PRTerrainLib/TerrainType.h b/extension/src/port/PRTerrainLib/TerrainType.h index 7965b375..a527743a 100644 --- a/extension/src/port/PRTerrainLib/TerrainType.h +++ b/extension/src/port/PRTerrainLib/TerrainType.h @@ -65,11 +65,17 @@ typedef struct /* Converts a floating point number to an integer by truncation, using the FISTP instruction */ +#ifdef _MSC_VER #define PR_FLOAT_TO_INTASM __asm \ { \ __asm fld PR_FCNV \ __asm fistp PR_ICNV \ } +#else +// PORT: x87 fld/fistp stores PR_FCNV rounded in the current (default round-to-nearest-even) mode; lrintf is +// that conversion without inline x86 assembly. +#define PR_FLOAT_TO_INTASM (PR_ICNV = lrintf(PR_FCNV)) +#endif #define PR_FLOAT_TO_FIXED(inreal, outint) \ { \ diff --git a/extension/src/port/UserInterface/PythonMiniMap.cpp b/extension/src/port/UserInterface/PythonMiniMap.cpp new file mode 100644 index 00000000..8f626aa4 --- /dev/null +++ b/extension/src/port/UserInterface/PythonMiniMap.cpp @@ -0,0 +1,1497 @@ +#include "StdAfx.h" +#include "../EterLib/StateManager.h" +#include "../EterLib/GrpSubImage.h" +#include "../EterLib/Camera.h" +#include "../EterPack/EterPackManager.h" + +#include "PythonMiniMap.h" +#include "PythonBackground.h" +#include "PythonCharacterManager.h" +#include "PythonGuild.h" + +#include "AbstractPlayer.h" + +#include "../EterPythonLib/PythonWindowManager.h" + +void CPythonMiniMap::AddObserver(DWORD dwVID, float fSrcX, float fSrcY) +{ + std::map::iterator f=m_kMap_dwVID_kObserver.find(dwVID); + if (m_kMap_dwVID_kObserver.end()==f) + { + SObserver kObserver; + kObserver.dwSrcTime=ELTimer_GetMSec(); + kObserver.dwDstTime=kObserver.dwSrcTime+1000; + kObserver.fSrcX=fSrcX; + kObserver.fSrcY=fSrcY; + kObserver.fDstX=fSrcX; + kObserver.fDstY=fSrcY; + kObserver.fCurX=fSrcX; + kObserver.fCurY=fSrcY; + m_kMap_dwVID_kObserver.insert(std::map::value_type(dwVID, kObserver)); + } + else + { + SObserver& rkObserver=f->second; + rkObserver.dwSrcTime=ELTimer_GetMSec(); + rkObserver.dwDstTime=rkObserver.dwSrcTime+1000; + rkObserver.fSrcX=fSrcX; + rkObserver.fSrcY=fSrcY; + rkObserver.fDstX=fSrcX; + rkObserver.fDstY=fSrcY; + rkObserver.fCurX=fSrcX; + rkObserver.fCurY=fSrcY; + } +} + +void CPythonMiniMap::MoveObserver(DWORD dwVID, float fDstX, float fDstY) +{ + std::map::iterator f=m_kMap_dwVID_kObserver.find(dwVID); + if (m_kMap_dwVID_kObserver.end()==f) + return; + + SObserver& rkObserver=f->second; + rkObserver.dwSrcTime=ELTimer_GetMSec(); + rkObserver.dwDstTime=rkObserver.dwSrcTime+1000; + rkObserver.fSrcX=rkObserver.fCurX; + rkObserver.fSrcY=rkObserver.fCurY; + rkObserver.fDstX=fDstX; + rkObserver.fDstY=fDstY; +} + +void CPythonMiniMap::RemoveObserver(DWORD dwVID) +{ + m_kMap_dwVID_kObserver.erase(dwVID); +} + +void CPythonMiniMap::SetCenterPosition(float fCenterX, float fCenterY) +{ + m_fCenterX = fCenterX; + m_fCenterY = fCenterY; + + CMapOutdoor& rkMap = CPythonBackground::Instance().GetMapOutdoorRef(); + for (BYTE byTerrainNum = 0; byTerrainNum < AROUND_AREA_NUM; ++byTerrainNum) + { + m_lpMiniMapTexture[byTerrainNum] = NULL; + CTerrain * pTerrain; + if (rkMap.GetTerrainPointer(byTerrainNum, &pTerrain)) + m_lpMiniMapTexture[byTerrainNum] = pTerrain->GetMiniMapTexture(); + } + + const TOutdoorMapCoordinate & rOutdoorMapCoord = rkMap.GetCurCoordinate(); + + m_fCenterCellX = (m_fCenterX - (float)(rOutdoorMapCoord.m_sTerrainCoordX * CTerrainImpl::TERRAIN_XSIZE)) / (float)(CTerrainImpl::CELLSCALE); + m_fCenterCellY = (m_fCenterY - (float)(rOutdoorMapCoord.m_sTerrainCoordY * CTerrainImpl::TERRAIN_YSIZE)) / (float)(CTerrainImpl::CELLSCALE); + + __SetPosition(); +} + +void CPythonMiniMap::Update(float fCenterX, float fCenterY) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.IsMapOutdoor()) + return; + + // 미니맵 그림 갱신 + if (m_fCenterX != fCenterX || m_fCenterY != fCenterY ) + SetCenterPosition(fCenterX, fCenterY); + + // 캐릭터 리스트 갱신 + m_OtherPCPositionVector.clear(); + m_PartyPCPositionVector.clear(); + m_NPCPositionVector.clear(); + m_MonsterPositionVector.clear(); + m_WarpPositionVector.clear(); + + float fooCellScale = 1.0f / ((float) CTerrainImpl::CELLSCALE); + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + + CInstanceBase* pkInstMain=rkChrMgr.GetMainInstancePtr(); + if (!pkInstMain) + return; + + CPythonCharacterManager::CharacterIterator i; + for(i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i) + { + CInstanceBase* pkInstEach=*i; + + TPixelPosition kInstancePosition; + pkInstEach->NEW_GetPixelPosition(&kInstancePosition); + float fDistanceFromCenterX = (kInstancePosition.x - m_fCenterX) * fooCellScale * m_fScale; + float fDistanceFromCenterY = (kInstancePosition.y - m_fCenterY) * fooCellScale * m_fScale; + if (fabs(fDistanceFromCenterX) >= m_fMiniMapRadius || fabs(fDistanceFromCenterY) >= m_fMiniMapRadius) + continue; + + float fDistanceFromCenter = sqrtf(fDistanceFromCenterX * fDistanceFromCenterX + fDistanceFromCenterY * fDistanceFromCenterY ); + if ( fDistanceFromCenter >= m_fMiniMapRadius ) + continue; + + TMarkPosition aMarkPosition; + + if (pkInstEach->IsPC() && !pkInstEach->IsInvisibility()) + { + if (pkInstEach == CPythonCharacterManager::Instance().GetMainInstancePtr()) + continue; + + aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + aMarkPosition.m_eNameColor=pkInstEach->GetNameColorIndex(); + if (aMarkPosition.m_eNameColor==CInstanceBase::NAMECOLOR_PARTY) + m_PartyPCPositionVector.push_back(aMarkPosition); + else + m_OtherPCPositionVector.push_back(aMarkPosition); + } + else if (pkInstEach->IsNPC()) + { + aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + + m_NPCPositionVector.push_back(aMarkPosition); + } + else if (pkInstEach->IsEnemy()) + { + aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + + m_MonsterPositionVector.push_back(aMarkPosition); + } + else if (pkInstEach->IsWarp()) + { + aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + + m_WarpPositionVector.push_back(aMarkPosition); + } + } + + { + DWORD dwCurTime=ELTimer_GetMSec(); + + std::map::iterator i; + for (i=m_kMap_dwVID_kObserver.begin(); i!=m_kMap_dwVID_kObserver.end(); ++i) + { + SObserver& rkObserver=i->second; + + float fPos=float(dwCurTime-rkObserver.dwSrcTime)/float(rkObserver.dwDstTime-rkObserver.dwSrcTime); + if (fPos<0.0f) fPos=0.0f; + else if (fPos>1.0f) fPos=1.0f; + + rkObserver.fCurX=(rkObserver.fDstX-rkObserver.fSrcX)*fPos+rkObserver.fSrcX; + rkObserver.fCurY=(rkObserver.fDstY-rkObserver.fSrcY)*fPos+rkObserver.fSrcY; + + TPixelPosition kInstancePosition; + kInstancePosition.x=rkObserver.fCurX; + kInstancePosition.y=rkObserver.fCurY; + kInstancePosition.z=0.0f; + + float fDistanceFromCenterX = (kInstancePosition.x - m_fCenterX) * fooCellScale * m_fScale; + float fDistanceFromCenterY = (kInstancePosition.y - m_fCenterY) * fooCellScale * m_fScale; + if (fabs(fDistanceFromCenterX) >= m_fMiniMapRadius || fabs(fDistanceFromCenterY) >= m_fMiniMapRadius) + continue; + + float fDistanceFromCenter = sqrtf(fDistanceFromCenterX * fDistanceFromCenterX + fDistanceFromCenterY * fDistanceFromCenterY ); + if ( fDistanceFromCenter >= m_fMiniMapRadius ) + continue; + + TMarkPosition aMarkPosition; + aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + aMarkPosition.m_eNameColor=CInstanceBase::NAMECOLOR_PARTY; + m_PartyPCPositionVector.push_back(aMarkPosition); + } + } + + { + TAtlasMarkInfoVector::iterator itor = m_AtlasWayPointInfoVector.begin(); + for (; itor != m_AtlasWayPointInfoVector.end(); ++itor) + { + TAtlasMarkInfo & rAtlasMarkInfo = *itor; + + if (TYPE_TARGET != rAtlasMarkInfo.m_byType) + continue; + + if (0 != rAtlasMarkInfo.m_dwChrVID) + { + CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(rAtlasMarkInfo.m_dwChrVID); + if (pInstance) + { + TPixelPosition kPixelPosition; + pInstance->NEW_GetPixelPosition(&kPixelPosition); + __UpdateWayPoint(&rAtlasMarkInfo, kPixelPosition.x, kPixelPosition.y); + } + } + + const float c_fMiniMapWindowRadius = 55.0f; + + float fDistanceFromCenterX = (rAtlasMarkInfo.m_fX - m_fCenterX) * fooCellScale * m_fScale; + float fDistanceFromCenterY = (rAtlasMarkInfo.m_fY - m_fCenterY) * fooCellScale * m_fScale; + float fDistanceFromCenter = sqrtf(fDistanceFromCenterX * fDistanceFromCenterX + fDistanceFromCenterY * fDistanceFromCenterY ); + + if (fDistanceFromCenter >= c_fMiniMapWindowRadius) + { + float fRadianX = acosf(fDistanceFromCenterX / fDistanceFromCenter); + float fRadianY = asinf(fDistanceFromCenterY / fDistanceFromCenter); + fDistanceFromCenterX = 55.0f * cosf(fRadianX); + fDistanceFromCenterY = 55.0f * sinf(fRadianY); + rAtlasMarkInfo.m_fMiniMapX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX + 2.0f; + rAtlasMarkInfo.m_fMiniMapY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY + 2.0f; + } + else + { + rAtlasMarkInfo.m_fMiniMapX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; + rAtlasMarkInfo.m_fMiniMapY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; + } + } + } +} + +void CPythonMiniMap::Render(float fScreenX, float fScreenY) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.IsMapOutdoor()) + return; + + if (!m_bShow) + return; + + if (!rkBG.IsMapReady()) + return; + + if (m_fScreenX != fScreenX || m_fScreenY != fScreenY) + { + m_fScreenX = fScreenX; + m_fScreenY = fScreenY; + __SetPosition(); + } + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + STATEMANAGER.SaveTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFF000000); + + STATEMANAGER.SetTexture(1, m_MiniMapFilterGraphicImageInstance.GetTexturePointer()->GetD3DTexture()); + STATEMANAGER.SetTransform(D3DTS_TEXTURE1, &m_matMiniMapCover); + + STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1); + STATEMANAGER.SetStreamSource(0, m_VertexBuffer.GetD3DVertexBuffer(), 20); + STATEMANAGER.SetIndices(m_IndexBuffer.GetD3DIndexBuffer(), 0); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorld); + + for (BYTE byTerrainNum = 0; byTerrainNum < AROUND_AREA_NUM; ++byTerrainNum) + { + LPDIRECT3DTEXTURE8 pMiniMapTexture = m_lpMiniMapTexture[byTerrainNum]; + STATEMANAGER.SetTexture(0, pMiniMapTexture); + if (pMiniMapTexture) + { + CStateManager& rkSttMgr=CStateManager::Instance(); + rkSttMgr.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, byTerrainNum * 4, 4, byTerrainNum * 6, 2); + } + else + { + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, byTerrainNum * 4, 4, byTerrainNum * 6, 2); + STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + } + } + + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); + + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG2); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAARG1); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ALPHAOP); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_COLOROP); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXCOORDINDEX); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSU); + STATEMANAGER.RestoreTextureStageState(1, D3DTSS_ADDRESSV); + + SetDiffuseOperation(); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matIdentity); + + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + + TInstancePositionVectorIterator aIterator; + + if (m_fScale >= 2.0f) + { + // Monster + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_MOB));//m_MarkTypeToColorMap[TYPE_MONSTER]); + aIterator = m_MonsterPositionVector.begin(); + while (aIterator != m_MonsterPositionVector.end()) + { + TMarkPosition & rPosition = *aIterator; + m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); + m_WhiteMark.Render(); + ++aIterator; + } + + // Other PC + aIterator = m_OtherPCPositionVector.begin(); + while (aIterator != m_OtherPCPositionVector.end()) + { + TMarkPosition & rPosition = *aIterator; + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(rPosition.m_eNameColor)); + m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); + m_WhiteMark.Render(); + ++aIterator; + } + + // Party PC + if (!m_PartyPCPositionVector.empty()) + { + float v = (1+sinf(CTimer::Instance().GetCurrentSecond()*6))/5+0.6; + D3DXCOLOR c(CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_PARTY));//(m_MarkTypeToColorMap[TYPE_PARTY]); + D3DXCOLOR d(v,v,v,1); + D3DXColorModulate(&c,&c,&d); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, (DWORD)c); + aIterator = m_PartyPCPositionVector.begin(); + while (aIterator != m_PartyPCPositionVector.end()) + { + TMarkPosition & rPosition = *aIterator; + m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); + m_WhiteMark.Render(); + ++aIterator; + } + } + } + + // NPC + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC)); + aIterator = m_NPCPositionVector.begin(); + while (aIterator != m_NPCPositionVector.end()) + { + TMarkPosition & rPosition = *aIterator; + m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); + m_WhiteMark.Render(); + ++aIterator; + } + + // Warp + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WARP)); + aIterator = m_WarpPositionVector.begin(); + while (aIterator != m_WarpPositionVector.end()) + { + TMarkPosition & rPosition = *aIterator; + m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); + m_WhiteMark.Render(); + ++aIterator; + } + + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ALPHAOP); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER); + + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + + // 캐릭터 마크 + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr(); + + if (pkInst) + { + float fRotation; + fRotation = (540.0f - pkInst->GetRotation()); + while(fRotation > 360.0f) + fRotation -= 360.0f; + while(fRotation < 0.0f) + fRotation += 360.0f; + + m_PlayerMark.SetRotation(fRotation); + m_PlayerMark.Render(); + } + + // Target + { + TAtlasMarkInfoVector::iterator itor = m_AtlasWayPointInfoVector.begin(); + for (; itor != m_AtlasWayPointInfoVector.end(); ++itor) + { + TAtlasMarkInfo & rAtlasMarkInfo = *itor; + + if (TYPE_TARGET != rAtlasMarkInfo.m_byType) + continue; + if (rAtlasMarkInfo.m_fMiniMapX <= 0.0f) + continue; + if (rAtlasMarkInfo.m_fMiniMapY <= 0.0f) + continue; + + __RenderTargetMark(rAtlasMarkInfo.m_fMiniMapX, rAtlasMarkInfo.m_fMiniMapY); + } + } + + CCamera* pkCmrCur=CCameraManager::Instance().GetCurrentCamera(); + + // 카메라 방향 + if (pkCmrCur) + { + m_MiniMapCameraraphicImageInstance.SetRotation(pkCmrCur->GetRoll()); + m_MiniMapCameraraphicImageInstance.Render(); + } + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER); +} + +void CPythonMiniMap::SetScale(float fScale) +{ + if (fScale >= 4.0f) + fScale = 4.0f; + if (fScale <= 0.5f) + fScale = 0.5f; + m_fScale = fScale; + + __SetPosition(); +} + +void CPythonMiniMap::ScaleUp() +{ + m_fScale *= 2.0f; + if (m_fScale >= 4.0f) + m_fScale = 4.0f; + __SetPosition(); +} + +void CPythonMiniMap::ScaleDown() +{ + m_fScale *= 0.5f; + if (m_fScale <= 0.5f) + m_fScale = 0.5f; + __SetPosition(); +} + +void CPythonMiniMap::SetMiniMapSize(float fWidth, float fHeight) +{ + m_fWidth = fWidth; + m_fHeight = fHeight; +} + +#pragma pack(push) +#pragma pack(1) +typedef struct _MINIMAPVERTEX +{ + float x, y, z; // position + float u, v; // normal +} MINIMAPVERTEX, *LPMINIMAPVERTEX; +#pragma pack(pop) + +bool CPythonMiniMap::Create() +{ + const std::string strImageRoot = "D:/ymir work/ui/"; + const std::string strImageFilter = strImageRoot + "minimap_image_filter.dds"; + const std::string strImageCamera = strImageRoot + "minimap_camera.dds"; + const std::string strPlayerMark = strImageRoot + "minimap/playermark.sub"; + const std::string strWhiteMark = strImageRoot + "minimap/whitemark.sub"; + + // 미니맵 커버 + CGraphicImage * pImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer(strImageFilter.c_str()); + m_MiniMapFilterGraphicImageInstance.SetImagePointer(pImage); + pImage = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer(strImageCamera.c_str()); + m_MiniMapCameraraphicImageInstance.SetImagePointer(pImage); + + m_matMiniMapCover._11 = 1.0f / ((float)m_MiniMapFilterGraphicImageInstance.GetWidth()); + m_matMiniMapCover._22 = 1.0f / ((float)m_MiniMapFilterGraphicImageInstance.GetHeight()); + m_matMiniMapCover._33 = 0.0f; + + // 캐릭터 마크 + CGraphicSubImage * pSubImage = (CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(strPlayerMark.c_str()); + m_PlayerMark.SetImagePointer(pSubImage); + + pSubImage = (CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(strWhiteMark.c_str()); + m_WhiteMark.SetImagePointer(pSubImage); + + char buf[256]; + for (int i = 0; i < MINI_WAYPOINT_IMAGE_COUNT; ++i) + { + sprintf(buf, "%sminimap/mini_waypoint%02d.sub", strImageRoot.c_str(), i+1); + m_MiniWayPointGraphicImageInstances[i].SetImagePointer((CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(buf)); + m_MiniWayPointGraphicImageInstances[i].SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN); + } + for (int j = 0; j < WAYPOINT_IMAGE_COUNT; ++j) + { + sprintf(buf, "%sminimap/waypoint%02d.sub", strImageRoot.c_str(), j+1); + m_WayPointGraphicImageInstances[j].SetImagePointer((CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(buf)); + m_WayPointGraphicImageInstances[j].SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN); + } + for (int k = 0; k < TARGET_MARK_IMAGE_COUNT; ++k) + { + sprintf(buf, "%sminimap/targetmark%02d.sub", strImageRoot.c_str(), k+1); + m_TargetMarkGraphicImageInstances[k].SetImagePointer((CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(buf)); + m_TargetMarkGraphicImageInstances[k].SetRenderingMode(CGraphicExpandedImageInstance::RENDERING_MODE_SCREEN); + } + + m_GuildAreaFlagImageInstance.SetImagePointer((CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer("d:/ymir work/ui/minimap/GuildArea01.sub")); + + // 그려질 폴리곤 세팅 +#pragma pack(push) +#pragma pack(1) + LPMINIMAPVERTEX lpMiniMapVertex; + LPMINIMAPVERTEX lpOrigMiniMapVertex; +#pragma pack(pop) + + if (!m_VertexBuffer.Create(36, D3DFVF_XYZ | D3DFVF_TEX1, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED) ) + { + return false; + } + + if (m_VertexBuffer.Lock((void **) &lpOrigMiniMapVertex)) + { + char * pchMiniMapVertex = (char *)lpOrigMiniMapVertex; + memset(pchMiniMapVertex, 0, sizeof(char) * 720); + lpMiniMapVertex = (LPMINIMAPVERTEX) pchMiniMapVertex; + + for (int iY = -3; iY <= 1; ++iY) + { + if (0 == iY%2) + continue; + float fY = 0.5f * ((float)iY); + for (int iX = -3; iX <= 1; ++iX) + { + if (0 == iX%2) + continue; + float fX = 0.5f * ((float)iX); + lpMiniMapVertex = (LPMINIMAPVERTEX) pchMiniMapVertex; + lpMiniMapVertex->x = fX; + lpMiniMapVertex->y = fY; + lpMiniMapVertex->z = 0.0f; + lpMiniMapVertex->u = 0.0f; + lpMiniMapVertex->v = 0.0f; + pchMiniMapVertex += 20; + lpMiniMapVertex = (LPMINIMAPVERTEX) pchMiniMapVertex; + lpMiniMapVertex->x = fX; + lpMiniMapVertex->y = fY + 1.0f; + lpMiniMapVertex->z = 0.0f; + lpMiniMapVertex->u = 0.0f; + lpMiniMapVertex->v = 1.0f; + pchMiniMapVertex += 20; + lpMiniMapVertex = (LPMINIMAPVERTEX) pchMiniMapVertex; + lpMiniMapVertex->x = fX + 1.0f; + lpMiniMapVertex->y = fY; + lpMiniMapVertex->z = 0.0f; + lpMiniMapVertex->u = 1.0f; + lpMiniMapVertex->v = 0.0f; + pchMiniMapVertex += 20; + lpMiniMapVertex = (LPMINIMAPVERTEX) pchMiniMapVertex; + lpMiniMapVertex->x = fX + 1.0f; + lpMiniMapVertex->y = fY + 1.0f; + lpMiniMapVertex->z = 0.0f; + lpMiniMapVertex->u = 1.0f; + lpMiniMapVertex->v = 1.0f; + pchMiniMapVertex += 20; + } + } + + m_VertexBuffer.Unlock(); + } + + if (!m_IndexBuffer.Create(54, D3DFMT_INDEX16)) + { + return false; + } + + WORD pwIndices[54] = + { + 0, 1, 2, 2, 1, 3, + 4, 5, 6, 6, 5, 7, + 8, 9, 10, 10, 9, 11, + + 12, 13, 14, 14, 13, 15, + 16, 17, 18, 18, 17, 19, + 20, 21, 22, 22, 21, 23, + + 24, 25, 26, 26, 25, 27, + 28, 29, 30, 30, 29, 31, + 32, 33, 34, 34, 33, 35 + }; + + void * pIndices; + + if (m_IndexBuffer.Lock(&pIndices)) + { + memcpy(pIndices, pwIndices, 54 * sizeof(WORD)); + m_IndexBuffer.Unlock(); + } + + return true; +} + +void CPythonMiniMap::__SetPosition() +{ + m_fMiniMapRadius = fMIN(6400.0f / ((float) CTerrainImpl::CELLSCALE) * m_fScale, 64.0f); + + m_matWorld._11 = m_fWidth * m_fScale; + m_matWorld._22 = m_fHeight * m_fScale; + m_matWorld._41 = (1.0f + m_fScale) * m_fWidth * 0.5f - m_fCenterCellX * m_fScale + m_fScreenX; + m_matWorld._42 = (1.0f + m_fScale) * m_fHeight * 0.5f - m_fCenterCellY * m_fScale + m_fScreenY; + + if (!m_MiniMapFilterGraphicImageInstance.IsEmpty()) + { + m_matMiniMapCover._41 = -(m_fScreenX) / ((float)m_MiniMapFilterGraphicImageInstance.GetWidth()); + m_matMiniMapCover._42 = -(m_fScreenY) / ((float)m_MiniMapFilterGraphicImageInstance.GetHeight()); + } + + if (!m_PlayerMark.IsEmpty()) + m_PlayerMark.SetPosition( ( m_fWidth - (float)m_PlayerMark.GetWidth() ) / 2.0f + m_fScreenX, + ( m_fHeight - (float)m_PlayerMark.GetHeight() ) / 2.0f + m_fScreenY ); + + if (!m_MiniMapCameraraphicImageInstance.IsEmpty()) + m_MiniMapCameraraphicImageInstance.SetPosition( ( m_fWidth - (float)m_MiniMapCameraraphicImageInstance.GetWidth() ) / 2.0f + m_fScreenX, + ( m_fHeight - (float)m_MiniMapCameraraphicImageInstance.GetHeight() ) / 2.0f + m_fScreenY ); +} + +////////////////////////////////////////////////////////////////////////// +// Atlas + +void CPythonMiniMap::ClearAtlasMarkInfo() +{ + m_AtlasNPCInfoVector.clear(); + m_AtlasWarpInfoVector.clear(); +} + +void CPythonMiniMap::RegisterAtlasMark(BYTE byType, const char * c_szName, long lx, long ly) +{ + TAtlasMarkInfo aAtlasMarkInfo; + + aAtlasMarkInfo.m_fX = float(lx); + aAtlasMarkInfo.m_fY = float(ly); + aAtlasMarkInfo.m_strText = c_szName; + + aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_WhiteMark.GetWidth() / 2.0f; + aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_WhiteMark.GetHeight() / 2.0f; + + switch(byType) + { + case CActorInstance::TYPE_NPC: + aAtlasMarkInfo.m_byType = TYPE_NPC; + m_AtlasNPCInfoVector.push_back(aAtlasMarkInfo); + break; + case CActorInstance::TYPE_WARP: + aAtlasMarkInfo.m_byType = TYPE_WARP; + { + int iPos = aAtlasMarkInfo.m_strText.find(" "); + if (iPos >= 0) + aAtlasMarkInfo.m_strText[iPos]=0; + + } + m_AtlasWarpInfoVector.push_back(aAtlasMarkInfo); + break; + } +} + +void CPythonMiniMap::ClearGuildArea() +{ + m_GuildAreaInfoVector.clear(); +} + +void CPythonMiniMap::RegisterGuildArea(DWORD dwID, DWORD dwGuildID, long x, long y, long width, long height) +{ + TGuildAreaInfo kGuildAreaInfo; + kGuildAreaInfo.dwGuildID = dwGuildID; + kGuildAreaInfo.lx = x; + kGuildAreaInfo.ly = y; + kGuildAreaInfo.lwidth = width; + kGuildAreaInfo.lheight = height; + m_GuildAreaInfoVector.push_back(kGuildAreaInfo); +} + +DWORD CPythonMiniMap::GetGuildAreaID(DWORD x, DWORD y) +{ + TGuildAreaInfoVectorIterator itor = m_GuildAreaInfoVector.begin(); + for (; itor != m_GuildAreaInfoVector.end(); ++itor) + { + TGuildAreaInfo & rAreaInfo = *itor; + + if (x >= rAreaInfo.lx) + if (y >= rAreaInfo.ly) + if (x <= rAreaInfo.lx + rAreaInfo.lwidth) + if (y <= rAreaInfo.ly + rAreaInfo.lheight) + { + return rAreaInfo.dwGuildID; + } + } + + return 0xffffffff; +} + +void CPythonMiniMap::CreateTarget(int iID, const char * c_szName) +{ + AddWayPoint(TYPE_TARGET, iID, 0.0f, 0.0f, c_szName); +} + +void CPythonMiniMap::UpdateTarget(int iID, int ix, int iy) +{ + TAtlasMarkInfo * pkInfo; + if (!__GetWayPoint(iID, &pkInfo)) + return; + + if (0 != pkInfo->m_dwChrVID) + { + if (CPythonCharacterManager::Instance().GetInstancePtr(pkInfo->m_dwChrVID)) + return; + } + + if (ix < m_dwAtlasBaseX) + return; + if (iy < m_dwAtlasBaseY) + return; + if (ix > m_dwAtlasBaseX+DWORD(m_fAtlasMaxX)) + return; + if (iy > m_dwAtlasBaseY+DWORD(m_fAtlasMaxY)) + return; + + __UpdateWayPoint(pkInfo, ix-int(m_dwAtlasBaseX), iy-int(m_dwAtlasBaseY)); +} + +void CPythonMiniMap::CreateTarget(int iID, const char * c_szName, DWORD dwVID) +{ + AddWayPoint(TYPE_TARGET, iID, 0.0f, 0.0f, c_szName, dwVID); +} + +void CPythonMiniMap::DeleteTarget(int iID) +{ + RemoveWayPoint(iID); +} + +void CPythonMiniMap::__LoadAtlasMarkInfo() +{ + ClearAtlasMarkInfo(); + ClearGuildArea(); + + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.IsMapOutdoor()) + return; + + CMapOutdoor& rkMap=rkBG.GetMapOutdoorRef(); + + // LOCALE + char szAtlasMarkInfoFileName[64+1]; + _snprintf(szAtlasMarkInfoFileName, sizeof(szAtlasMarkInfoFileName), "%s/map/%s_point.txt", LocaleService_GetLocalePath(), rkMap.GetName().c_str()); + // END_OF_LOCALE + + CTokenVectorMap stTokenVectorMap; + + if (!LoadMultipleTextData(szAtlasMarkInfoFileName, stTokenVectorMap)) + { + Tracef(" CPythonMiniMap::__LoadAtlasMarkInfo File Load %s ERROR\n", szAtlasMarkInfoFileName); + return; + } + + const std::string strType[TYPE_COUNT] = { "OPC", "OPCPVP", "OPCPVPSELF", "NPC", "MONSTER", "WARP", "WAYPOINT" }; + + for (DWORD i = 0; i < stTokenVectorMap.size(); ++i) + { + char szMarkInfoName[32+1]; + _snprintf(szMarkInfoName, sizeof(szMarkInfoName), "%d", i); + + if (stTokenVectorMap.end() == stTokenVectorMap.find(szMarkInfoName)) + continue; + + const CTokenVector & rVector = stTokenVectorMap[szMarkInfoName]; + + const std::string & c_rstrType = rVector[0].c_str(); + const std::string & c_rstrPositionX = rVector[1].c_str(); + const std::string & c_rstrPositionY = rVector[2].c_str(); + const std::string & c_rstrText = rVector[3].c_str(); + + TAtlasMarkInfo aAtlasMarkInfo; + + for ( int i = 0; i < TYPE_COUNT; ++i) + { + if (0 == c_rstrType.compare(strType[i])) + aAtlasMarkInfo.m_byType = (BYTE)i; + } + aAtlasMarkInfo.m_fX = atof(c_rstrPositionX.c_str()); + aAtlasMarkInfo.m_fY = atof(c_rstrPositionY.c_str()); + aAtlasMarkInfo.m_strText = c_rstrText; + + aAtlasMarkInfo.m_fScreenX = aAtlasMarkInfo.m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_WhiteMark.GetWidth() / 2.0f; + aAtlasMarkInfo.m_fScreenY = aAtlasMarkInfo.m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_WhiteMark.GetHeight() / 2.0f; + + switch(aAtlasMarkInfo.m_byType) + { + case TYPE_NPC: + m_AtlasNPCInfoVector.push_back(aAtlasMarkInfo); + break; + case TYPE_WARP: + m_AtlasWarpInfoVector.push_back(aAtlasMarkInfo); + break; + } + } +} + +bool CPythonMiniMap::LoadAtlas() +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.IsMapOutdoor()) + return false; + + CMapOutdoor& rkMap=rkBG.GetMapOutdoorRef(); + + const char* playerMarkFileName = "d:/ymir work/ui/minimap/playermark.sub"; + + char atlasFileName[1024+1]; + snprintf(atlasFileName, sizeof(atlasFileName), "%s/atlas.sub", rkMap.GetName().c_str()); + if (!CEterPackManager::Instance().isExist(atlasFileName)) + { + snprintf(atlasFileName, sizeof(atlasFileName), "d:/ymir work/ui/atlas/%s/atlas.sub", rkMap.GetName().c_str()); + } + + m_AtlasImageInstance.Destroy(); + m_AtlasPlayerMark.Destroy(); + CGraphicImage* pkGrpImgAtlas = (CGraphicImage *) CResourceManager::Instance().GetResourcePointer(atlasFileName); + if (pkGrpImgAtlas) + { + m_AtlasImageInstance.SetImagePointer(pkGrpImgAtlas); + + if (pkGrpImgAtlas->IsEmpty()) + m_bAtlas=false; + else + m_bAtlas=true; + } + else + { + } + m_AtlasPlayerMark.SetImagePointer((CGraphicSubImage *) CResourceManager::Instance().GetResourcePointer(playerMarkFileName)); + + short sTerrainCountX, sTerrainCountY; + rkMap.GetBaseXY(&m_dwAtlasBaseX, &m_dwAtlasBaseY); + rkMap.GetTerrainCount(&sTerrainCountX, &sTerrainCountY); + m_fAtlasMaxX = (float) sTerrainCountX * static_cast(CTerrainImpl::TERRAIN_XSIZE); + m_fAtlasMaxY = (float) sTerrainCountY * static_cast(CTerrainImpl::TERRAIN_YSIZE); + + m_fAtlasImageSizeX = (float) m_AtlasImageInstance.GetWidth(); + m_fAtlasImageSizeY = (float) m_AtlasImageInstance.GetHeight(); + + __LoadAtlasMarkInfo(); + + if (m_bShowAtlas) + OpenAtlasWindow(); + + return true; +} + +void CPythonMiniMap::__GlobalPositionToAtlasPosition(long lx, long ly, float * pfx, float * pfy) +{ + *pfx = lx / m_fAtlasMaxX * m_fAtlasImageSizeX; + *pfy = ly / m_fAtlasMaxY * m_fAtlasImageSizeY; +} + +void CPythonMiniMap::UpdateAtlas() +{ + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr(); + + if (pkInst) + { + TPixelPosition kInstPos; + pkInst->NEW_GetPixelPosition(&kInstPos); + + float fRotation; + fRotation = (540.0f - pkInst->GetRotation()); + while(fRotation > 360.0f) + fRotation -= 360.0f; + while(fRotation < 0.0f) + fRotation += 360.0f; + + m_AtlasPlayerMark.SetPosition(kInstPos.x / m_fAtlasMaxX * m_fAtlasImageSizeX - (float)m_AtlasPlayerMark.GetWidth() / 2.0f, + kInstPos.y / m_fAtlasMaxY * m_fAtlasImageSizeY - (float)m_AtlasPlayerMark.GetHeight() / 2.0f); + m_AtlasPlayerMark.SetRotation(fRotation); + } + + { + TGuildAreaInfoVectorIterator itor = m_GuildAreaInfoVector.begin(); + for (; itor != m_GuildAreaInfoVector.end(); ++itor) + { + TGuildAreaInfo & rInfo = *itor; + __GlobalPositionToAtlasPosition(rInfo.lx, rInfo.ly, &rInfo.fsxRender, &rInfo.fsyRender); + __GlobalPositionToAtlasPosition(rInfo.lx+rInfo.lwidth, rInfo.ly+rInfo.lheight, &rInfo.fexRender, &rInfo.feyRender); + } + } +} + +void CPythonMiniMap::RenderAtlas(float fScreenX, float fScreenY) +{ + if (!m_bShowAtlas) + return; + + if (m_fAtlasScreenX != fScreenX || m_fAtlasScreenY != fScreenY) + { + m_matWorldAtlas._41 = fScreenX; + m_matWorldAtlas._42 = fScreenY; + m_fAtlasScreenX = fScreenX; + m_fAtlasScreenY = fScreenY; + } + + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matWorldAtlas); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT); + m_AtlasImageInstance.Render(); + + STATEMANAGER.SaveRenderState(D3DRS_TEXTUREFACTOR, 0xFFFFFFFF); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); + STATEMANAGER.SaveTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC)); + m_AtlasMarkInfoVectorIterator = m_AtlasNPCInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasNPCInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + m_WhiteMark.SetPosition(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY); + m_WhiteMark.Render(); + ++m_AtlasMarkInfoVectorIterator; + } + + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WARP)); + m_AtlasMarkInfoVectorIterator = m_AtlasWarpInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasWarpInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + m_WhiteMark.SetPosition(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY); + m_WhiteMark.Render(); + ++m_AtlasMarkInfoVectorIterator; + } + + STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); + STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WAYPOINT)); + m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin(); + for (; m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end(); ++m_AtlasMarkInfoVectorIterator) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + + if (rAtlasMarkInfo.m_fScreenX <= 0.0f) + continue; + if (rAtlasMarkInfo.m_fScreenY <= 0.0f) + continue; + + if (TYPE_TARGET == rAtlasMarkInfo.m_byType) + { + __RenderMiniWayPointMark(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY); + } + else + { + __RenderWayPointMark(rAtlasMarkInfo.m_fScreenX, rAtlasMarkInfo.m_fScreenY); + } + } + + STATEMANAGER.RestoreRenderState(D3DRS_TEXTUREFACTOR); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG1); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLORARG2); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_COLOROP); + + if ((ELTimer_GetMSec() / 500) % 2) + m_AtlasPlayerMark.Render(); + + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER); + STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER); + STATEMANAGER.SetTransform(D3DTS_WORLD, &m_matIdentity); + + { + TGuildAreaInfoVectorIterator itor = m_GuildAreaInfoVector.begin(); + for (; itor != m_GuildAreaInfoVector.end(); ++itor) + { + TGuildAreaInfo & rInfo = *itor; + + m_GuildAreaFlagImageInstance.SetPosition(fScreenX+(rInfo.fsxRender+rInfo.fexRender)/2.0f - m_GuildAreaFlagImageInstance.GetWidth()/2, + fScreenY+(rInfo.fsyRender+rInfo.feyRender)/2.0f - m_GuildAreaFlagImageInstance.GetHeight()/2); + m_GuildAreaFlagImageInstance.Render(); + +// CScreen::RenderBar2d(fScreenX+rInfo.fsxRender, +// fScreenY+rInfo.fsyRender, +// fScreenX+rInfo.fexRender, +// fScreenY+rInfo.feyRender); + } + } +} + +bool CPythonMiniMap::GetPickedInstanceInfo(float fScreenX, float fScreenY, std::string & rReturnName, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor) +{ + float fDistanceFromMiniMapCenterX = fScreenX - m_fScreenX - m_fWidth * 0.5f; + float fDistanceFromMiniMapCenterY = fScreenY - m_fScreenY - m_fHeight * 0.5f; + + if (sqrtf(fDistanceFromMiniMapCenterX * fDistanceFromMiniMapCenterX + fDistanceFromMiniMapCenterY * fDistanceFromMiniMapCenterY) > m_fMiniMapRadius ) + return false; + + float fRealX = m_fCenterX + fDistanceFromMiniMapCenterX / m_fScale * ((float) CTerrainImpl::CELLSCALE); + float fRealY = m_fCenterY + fDistanceFromMiniMapCenterY / m_fScale * ((float) CTerrainImpl::CELLSCALE); + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr(); + + if (pkInst) + { + TPixelPosition kInstPos; + pkInst->NEW_GetPixelPosition(&kInstPos); + + if (fabs(kInstPos.x - fRealX) < ((float) CTerrainImpl::CELLSCALE) * 6.0f / m_fScale && + fabs(kInstPos.y - fRealY) < ((float) CTerrainImpl::CELLSCALE) * 6.0f / m_fScale) + { + rReturnName = pkInst->GetNameString(); + *pReturnPosX = kInstPos.x; + *pReturnPosY = kInstPos.y; + *pdwTextColor = pkInst->GetNameColor(); + return true; + } + } + + if (m_fScale < 1.0f) + return false; + + CPythonCharacterManager& rkChrMgr=CPythonCharacterManager::Instance(); + CPythonCharacterManager::CharacterIterator i; + for(i = rkChrMgr.CharacterInstanceBegin(); i!=rkChrMgr.CharacterInstanceEnd(); ++i) + { + CInstanceBase* pkInstEach=*i; + if (pkInstEach->IsInvisibility()) + continue; + if (m_fScale < 2.0f && (pkInstEach->IsEnemy() || pkInstEach->IsPC())) + continue; + TPixelPosition kInstancePosition; + pkInstEach->NEW_GetPixelPosition(&kInstancePosition); + + if (fabs(kInstancePosition.x - fRealX) < ((float) CTerrainImpl::CELLSCALE) * 3.0f / m_fScale && + fabs(kInstancePosition.y - fRealY) < ((float) CTerrainImpl::CELLSCALE) * 3.0f / m_fScale) + { + rReturnName = pkInstEach->GetNameString(); + *pReturnPosX = kInstancePosition.x; + *pReturnPosY = kInstancePosition.y; + *pdwTextColor = pkInstEach->GetNameColor(); + return true; + } + } + return false; +} + + +bool CPythonMiniMap::GetAtlasInfo(float fScreenX, float fScreenY, std::string & rReturnString, float * pReturnPosX, float * pReturnPosY, DWORD * pdwTextColor, DWORD * pdwGuildID) +{ + float fRealX = (fScreenX - m_fAtlasScreenX) * (m_fAtlasMaxX / m_fAtlasImageSizeX); + float fRealY = (fScreenY - m_fAtlasScreenY) * (m_fAtlasMaxY / m_fAtlasImageSizeY); + + //((float) CTerrainImpl::CELLSCALE) * 10.0f + float fCheckWidth = (m_fAtlasMaxX / m_fAtlasImageSizeX) * 5.0f; + float fCheckHeight = (m_fAtlasMaxY / m_fAtlasImageSizeY) * 5.0f; + + CInstanceBase * pkInst = CPythonCharacterManager::Instance().GetMainInstancePtr(); + + if (pkInst) + { + TPixelPosition kInstPos; + pkInst->NEW_GetPixelPosition(&kInstPos); + + if (kInstPos.x-fCheckWidthfRealX && + kInstPos.y-fCheckHeightfRealY) + { + rReturnString = pkInst->GetNameString(); + *pReturnPosX = kInstPos.x; + *pReturnPosY = kInstPos.y; + *pdwTextColor = pkInst->GetNameColor(); + return true; + } + } + + m_AtlasMarkInfoVectorIterator = m_AtlasNPCInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasNPCInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + + if (rAtlasMarkInfo.m_fX-fCheckWidth/2fRealX && + rAtlasMarkInfo.m_fY-fCheckWidth/2fRealY) + { + rReturnString = rAtlasMarkInfo.m_strText; + *pReturnPosX = rAtlasMarkInfo.m_fX; + *pReturnPosY = rAtlasMarkInfo.m_fY; + *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC);//m_MarkTypeToColorMap[rAtlasMarkInfo.m_byType]; + return true; + } + ++m_AtlasMarkInfoVectorIterator; + } + + m_AtlasMarkInfoVectorIterator = m_AtlasWarpInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasWarpInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + if (rAtlasMarkInfo.m_fX-fCheckWidth/2fRealX && + rAtlasMarkInfo.m_fY-fCheckWidth/2fRealY) + { + rReturnString = rAtlasMarkInfo.m_strText; + *pReturnPosX = rAtlasMarkInfo.m_fX; + *pReturnPosY = rAtlasMarkInfo.m_fY; + *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WARP);//m_MarkTypeToColorMap[rAtlasMarkInfo.m_byType]; + return true; + } + ++m_AtlasMarkInfoVectorIterator; + } + + m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + if (rAtlasMarkInfo.m_fScreenX > 0.0f) + if (rAtlasMarkInfo.m_fScreenY > 0.0f) + if (rAtlasMarkInfo.m_fX-fCheckWidth/2fRealX && + rAtlasMarkInfo.m_fY-fCheckWidth/2fRealY) + { + rReturnString = rAtlasMarkInfo.m_strText; + *pReturnPosX = rAtlasMarkInfo.m_fX; + *pReturnPosY = rAtlasMarkInfo.m_fY; + *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_WAYPOINT);//m_MarkTypeToColorMap[rAtlasMarkInfo.m_byType]; + return true; + } + ++m_AtlasMarkInfoVectorIterator; + } + + TGuildAreaInfoVector::iterator itor = m_GuildAreaInfoVector.begin(); + for (; itor!=m_GuildAreaInfoVector.end(); ++itor) + { + TGuildAreaInfo & rInfo = *itor; + if (fScreenX - m_fAtlasScreenX >= rInfo.fsxRender) + if (fScreenY - m_fAtlasScreenY >= rInfo.fsyRender) + if (fScreenX - m_fAtlasScreenX <= rInfo.fexRender) + if (fScreenY - m_fAtlasScreenY <= rInfo.feyRender) + { + if (CPythonGuild::Instance().GetGuildName(rInfo.dwGuildID, &rReturnString)) + { + *pdwGuildID = rInfo.dwGuildID; + } + else + { + rReturnString = "empty_guild_area"; + } + + *pReturnPosX = rInfo.lx + rInfo.lwidth/2; + *pReturnPosY = rInfo.ly + rInfo.lheight/2; + *pdwTextColor = CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_PARTY); + return true; + } + } + + return false; +} + +bool CPythonMiniMap::GetAtlasSize(float * pfSizeX, float * pfSizeY) +{ + CPythonBackground& rkBG=CPythonBackground::Instance(); + if (!rkBG.IsMapOutdoor()) + return false; + + *pfSizeX = m_fAtlasImageSizeX; + *pfSizeY = m_fAtlasImageSizeY; + + return true; +} + +// Atlas +////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////// +// WayPoint +void CPythonMiniMap::AddWayPoint(BYTE byType, DWORD dwID, float fX, float fY, std::string strText, DWORD dwChrVID) +{ + m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + if (rAtlasMarkInfo.m_dwID == dwID) + return; + ++m_AtlasMarkInfoVectorIterator; + } + + TAtlasMarkInfo aAtlasMarkInfo; + aAtlasMarkInfo.m_byType = byType; + aAtlasMarkInfo.m_dwID = dwID; + aAtlasMarkInfo.m_fX = fX; + aAtlasMarkInfo.m_fY = fY; + aAtlasMarkInfo.m_fScreenX = 0.0f; + aAtlasMarkInfo.m_fScreenY = 0.0f; + aAtlasMarkInfo.m_fMiniMapX = 0.0f; + aAtlasMarkInfo.m_fMiniMapY = 0.0f; + aAtlasMarkInfo.m_strText = strText; + aAtlasMarkInfo.m_dwChrVID = dwChrVID; + __UpdateWayPoint(&aAtlasMarkInfo, fX, fY); + m_AtlasWayPointInfoVector.push_back(aAtlasMarkInfo); + +} + +void CPythonMiniMap::RemoveWayPoint(DWORD dwID) +{ + m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.begin(); + while (m_AtlasMarkInfoVectorIterator != m_AtlasWayPointInfoVector.end()) + { + TAtlasMarkInfo & rAtlasMarkInfo = *m_AtlasMarkInfoVectorIterator; + if (rAtlasMarkInfo.m_dwID == dwID) + { + m_AtlasMarkInfoVectorIterator = m_AtlasWayPointInfoVector.erase(m_AtlasMarkInfoVectorIterator); + return; + } + ++m_AtlasMarkInfoVectorIterator; + } +} + +bool CPythonMiniMap::__GetWayPoint(DWORD dwID, TAtlasMarkInfo ** ppkInfo) +{ + TAtlasMarkInfoVectorIterator itor = m_AtlasWayPointInfoVector.begin(); + for (; itor != m_AtlasWayPointInfoVector.end(); ++itor) + { + TAtlasMarkInfo & rInfo = *itor; + if (dwID == rInfo.m_dwID) + { + *ppkInfo = &rInfo; + return true; + } + } + + return false; +} + +void CPythonMiniMap::__UpdateWayPoint(TAtlasMarkInfo * pkInfo, int ix, int iy) +{ + pkInfo->m_fX = float(ix); + pkInfo->m_fY = float(iy); + pkInfo->m_fScreenX = pkInfo->m_fX / m_fAtlasMaxX * m_fAtlasImageSizeX; + pkInfo->m_fScreenY = pkInfo->m_fY / m_fAtlasMaxY * m_fAtlasImageSizeY; +} + +// WayPoint +////////////////////////////////////////////////////////////////////////// + +void CPythonMiniMap::__RenderWayPointMark(int ixCenter, int iyCenter) +{ + int iNum = (ELTimer_GetMSec() / 67) % WAYPOINT_IMAGE_COUNT; + + CGraphicImageInstance & rInstance = m_WayPointGraphicImageInstances[iNum]; + rInstance.SetPosition(ixCenter - rInstance.GetWidth()/2, iyCenter - rInstance.GetHeight()/2); + rInstance.Render(); +} + +void CPythonMiniMap::__RenderMiniWayPointMark(int ixCenter, int iyCenter) +{ + int iNum = (ELTimer_GetMSec() / 67) % MINI_WAYPOINT_IMAGE_COUNT; + + CGraphicImageInstance & rInstance = m_MiniWayPointGraphicImageInstances[iNum]; + rInstance.SetPosition(ixCenter - rInstance.GetWidth()/2, iyCenter - rInstance.GetHeight()/2); + rInstance.Render(); +} + +void CPythonMiniMap::__RenderTargetMark(int ixCenter, int iyCenter) +{ + int iNum = (ELTimer_GetMSec() / 80) % TARGET_MARK_IMAGE_COUNT; + + CGraphicImageInstance & rInstance = m_TargetMarkGraphicImageInstances[iNum]; + rInstance.SetPosition(ixCenter - rInstance.GetWidth()/2, iyCenter - rInstance.GetHeight()/2); + rInstance.Render(); +} + +void CPythonMiniMap::AddSignalPoint(float fX, float fY) +{ + static unsigned int g_id = 255; + + TSignalPoint sp; + sp.id = g_id; + sp.v2Pos.x = fX; + sp.v2Pos.y = fY; + + m_SignalPointVector.push_back(sp); + + AddWayPoint(TYPE_WAYPOINT, g_id, fX, fY, ""); + + g_id++; +} + +void CPythonMiniMap::ClearAllSignalPoint() +{ + std::vector::iterator it; + for(it = m_SignalPointVector.begin();it!=m_SignalPointVector.end();++it) + { + RemoveWayPoint(it->id); + } + m_SignalPointVector.clear(); +} + +void CPythonMiniMap::RegisterAtlasWindow(PyObject* poHandler) +{ + m_poHandler = poHandler; +} + +void CPythonMiniMap::UnregisterAtlasWindow() +{ + m_poHandler = 0; +} + +void CPythonMiniMap::OpenAtlasWindow() +{ + if (m_poHandler) + { + PyCallClassMemberFunc(m_poHandler,"Show", Py_BuildValue("()")); + } +} + +void CPythonMiniMap::SetAtlasCenterPosition(int x, int y) +{ + if (m_poHandler) + { + //int sw = UI::CWindowManager::Instance().GetScreenWidth(); + //int sh = UI::CWindowManager::Instance().GetScreenHeight(); + //PyCallClassMemberFunc(m_poHandler,"SetPosition", Py_BuildValue("(ii)",sw/2+x,sh/2+y)); + PyCallClassMemberFunc(m_poHandler,"SetCenterPositionAdjust", Py_BuildValue("(ii)",x,y)); + } +} + +bool CPythonMiniMap::IsAtlas() +{ + return m_bAtlas; +} + +void CPythonMiniMap::ShowAtlas() +{ + m_bShowAtlas=true; +} + +void CPythonMiniMap::HideAtlas() +{ + m_bShowAtlas=false; +} + +bool CPythonMiniMap::CanShowAtlas() +{ + return m_bShowAtlas; +} + +bool CPythonMiniMap::CanShow() +{ + return m_bShow; +} + +void CPythonMiniMap::Show() +{ + m_bShow=true; +} + +void CPythonMiniMap::Hide() +{ + m_bShow=false; +} + +void CPythonMiniMap::__Initialize() +{ + m_poHandler = 0; + + SetMiniMapSize(128.0f, 128.0f); + + m_fScale = 2.0f; + + m_fCenterX = m_fWidth * 0.5f; + m_fCenterY = m_fHeight * 0.5f; + + m_fScreenX = 0.0f; + m_fScreenY = 0.0f; + + m_fAtlasScreenX = 0.0f; + m_fAtlasScreenY = 0.0f; + + m_dwAtlasBaseX = 0; + m_dwAtlasBaseY = 0; + + m_fAtlasMaxX = 0.0f; + m_fAtlasMaxY = 0.0f; + + m_fAtlasImageSizeX = 0.0f; + m_fAtlasImageSizeY = 0.0f; + + m_bAtlas = false; + + m_bShow = false; + m_bShowAtlas = false; + + D3DXMatrixIdentity(&m_matIdentity); + D3DXMatrixIdentity(&m_matWorld); + D3DXMatrixIdentity(&m_matMiniMapCover); + D3DXMatrixIdentity(&m_matWorldAtlas); +} + +void CPythonMiniMap::Destroy() +{ + ClearAllSignalPoint(); + m_poHandler = 0; + + m_VertexBuffer.Destroy(); + m_IndexBuffer.Destroy(); + + m_PlayerMark.Destroy(); + + m_MiniMapFilterGraphicImageInstance.Destroy(); + m_MiniMapCameraraphicImageInstance.Destroy(); + + m_AtlasWayPointInfoVector.clear(); + m_AtlasImageInstance.Destroy(); + m_AtlasPlayerMark.Destroy(); + m_WhiteMark.Destroy(); + + for (int i = 0; i < MINI_WAYPOINT_IMAGE_COUNT; ++i) + m_MiniWayPointGraphicImageInstances[i].Destroy(); + for (int j = 0; j < WAYPOINT_IMAGE_COUNT; ++j) + m_WayPointGraphicImageInstances[j].Destroy(); + for (int k = 0; k < TARGET_MARK_IMAGE_COUNT; ++k) + m_TargetMarkGraphicImageInstances[k].Destroy(); + + m_GuildAreaFlagImageInstance.Destroy(); + + __Initialize(); +} + +CPythonMiniMap::CPythonMiniMap() +{ + __Initialize(); +} + +CPythonMiniMap::~CPythonMiniMap() +{ + Destroy(); +} diff --git a/extension/src/port/UserInterface/PythonMiniMapModule.cpp b/extension/src/port/UserInterface/PythonMiniMapModule.cpp new file mode 100644 index 00000000..e6140ac1 --- /dev/null +++ b/extension/src/port/UserInterface/PythonMiniMapModule.cpp @@ -0,0 +1,357 @@ +#include "StdAfx.h" +#include "PythonMiniMap.h" + +PyObject * miniMapSetScale(PyObject * poSelf, PyObject * poArgs) +{ + float fScale; + if (!PyTuple_GetFloat(poArgs, 0, &fScale)) + return Py_BuildException(); + + CPythonMiniMap::Instance().SetScale(fScale); + return Py_BuildNone(); +} + +PyObject * miniMapSetCenterPosition(PyObject * poSelf, PyObject * poArgs) +{ + float fCenterX; + if (!PyTuple_GetFloat(poArgs, 0, &fCenterX)) + return Py_BuildException(); + + float fCenterY; + if (!PyTuple_GetFloat(poArgs, 1, &fCenterY)) + return Py_BuildException(); + + CPythonMiniMap::Instance().SetCenterPosition(fCenterX, fCenterY); + return Py_BuildNone(); +} + + +PyObject * miniMapSetMiniMapSize(PyObject * poSelf, PyObject * poArgs) +{ + float fWidth; + if (!PyTuple_GetFloat(poArgs, 0, &fWidth)) + return Py_BuildException(); + + float fHeight; + if (!PyTuple_GetFloat(poArgs, 1, &fHeight)) + return Py_BuildException(); + + CPythonMiniMap::Instance().SetMiniMapSize(fWidth, fHeight); + return Py_BuildNone(); +} + +PyObject * miniMapDestroy(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().Destroy(); + return Py_BuildNone(); +} + +PyObject * miniMapCreate(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().Create(); + return Py_BuildNone(); +} + +PyObject * miniMapUpdate(PyObject * poSelf, PyObject * poArgs) +{ + float fCenterX; + if (!PyTuple_GetFloat(poArgs, 0, &fCenterX)) + return Py_BuildException(); + + float fCenterY; + if (!PyTuple_GetFloat(poArgs, 1, &fCenterY)) + return Py_BuildException(); + + CPythonMiniMap::Instance().Update(fCenterX, fCenterY); + return Py_BuildNone(); +} + +PyObject * miniMapRender(PyObject * poSelf, PyObject * poArgs) +{ + float fScrrenX; + if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX)) + return Py_BuildException(); + + float fScrrenY; + if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY)) + return Py_BuildException(); + + CPythonMiniMap::Instance().Render(fScrrenX, fScrrenY); + return Py_BuildNone(); +} + +PyObject * miniMapShow(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().Show(); + return Py_BuildNone(); +} + +PyObject * miniMapHide(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().Hide(); + return Py_BuildNone(); +} + +PyObject * miniMapisShow(PyObject * poSelf, PyObject * poArgs) +{ + bool bShow = CPythonMiniMap::Instance().CanShow(); + return Py_BuildValue("b", bShow); +} + +PyObject * miniMapScaleUp(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().ScaleUp(); + return Py_BuildNone(); +} + +PyObject * miniMapScaleDown(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().ScaleDown(); + return Py_BuildNone(); +} + +PyObject * miniMapGetInfo(PyObject * poSelf, PyObject * poArgs) +{ + float fScrrenX; + if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX)) + return Py_BuildException(); + + float fScrrenY; + if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY)) + return Py_BuildException(); + + std::string aString; + float fPosX, fPosY; + DWORD dwTextColor; + bool bFind = CPythonMiniMap::Instance().GetPickedInstanceInfo(fScrrenX, fScrrenY, aString, &fPosX, &fPosY, &dwTextColor); + int iPosX, iPosY; + PR_FLOAT_TO_INT(fPosX, iPosX); + PR_FLOAT_TO_INT(fPosY, iPosY); + iPosX /= 100; + iPosY /= 100; + return Py_BuildValue("isiil", (int)bFind, aString.c_str(), iPosX, iPosY, (signed) dwTextColor); +} + +////////////////////////////////////////////////////////////////////////// +// Atlas +PyObject * miniMapLoadAtlas(PyObject * poSelf, PyObject * poArgs) +{ + if (!CPythonMiniMap::Instance().LoadAtlas()) + TraceError("CPythonMiniMap::Instance().LoadAtlas() Failed"); + return Py_BuildNone(); +} + +PyObject * miniMapUpdateAtlas(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().UpdateAtlas(); + return Py_BuildNone(); +} + +PyObject * miniMapRenderAtlas(PyObject * poSelf, PyObject * poArgs) +{ + float fScrrenX; + if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX)) + return Py_BuildException(); + + float fScrrenY; + if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY)) + return Py_BuildException(); + + CPythonMiniMap::Instance().RenderAtlas(fScrrenX, fScrrenY); + return Py_BuildNone(); +} + +PyObject * miniMapShowAtlas(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().ShowAtlas(); + return Py_BuildNone(); +} + +PyObject * miniMapHideAtlas(PyObject * poSelf, PyObject * poArgs) +{ + CPythonMiniMap::Instance().HideAtlas(); + return Py_BuildNone(); +} + +PyObject * miniMapisShowAtlas(PyObject * poSelf, PyObject * poArgs) +{ + bool bShow = CPythonMiniMap::Instance().CanShowAtlas(); + return Py_BuildValue("b", bShow); +} + +PyObject * miniMapIsAtlas(PyObject * poSelf, PyObject * poArgs) +{ + bool isData = CPythonMiniMap::Instance().IsAtlas(); + return Py_BuildValue("b", isData); +} + + +PyObject * miniMapGetAtlasInfo(PyObject * poSelf, PyObject * poArgs) +{ + float fScrrenX; + if (!PyTuple_GetFloat(poArgs, 0, &fScrrenX)) + return Py_BuildException(); + float fScrrenY; + if (!PyTuple_GetFloat(poArgs, 1, &fScrrenY)) + return Py_BuildException(); + + std::string aString = ""; + float fPosX = 0.0f; + float fPosY = 0.0f; + DWORD dwTextColor = 0; + DWORD dwGuildID = 0; + bool bFind = CPythonMiniMap::Instance().GetAtlasInfo(fScrrenX, fScrrenY, aString, &fPosX, &fPosY, &dwTextColor, &dwGuildID); + int iPosX, iPosY; + PR_FLOAT_TO_INT(fPosX, iPosX); + PR_FLOAT_TO_INT(fPosY, iPosY); + iPosX /= 100; + iPosY /= 100; + return Py_BuildValue("isiili", (int)bFind, aString.c_str(), iPosX, iPosY, (signed) dwTextColor, dwGuildID); +} + +PyObject * miniMapGetAtlasSize(PyObject * poSelf, PyObject * poArgs) +{ + float fSizeX, fSizeY; + bool bGet = CPythonMiniMap::Instance().GetAtlasSize(&fSizeX, &fSizeY); + +/* + float fSizeXoo256 = fSizeX / 256.0f; + float fSizeYoo256 = fSizeY / 256.0f; + + if (fSizeXoo256 >= fSizeYoo256) + { + fSizeX /= fSizeYoo256; + fSizeY = 256.0f; + } + else + { + fSizeX = 256.0f; + fSizeY /= fSizeXoo256; + } +*/ + + int iSizeX, iSizeY; + PR_FLOAT_TO_INT(fSizeX, iSizeX); + PR_FLOAT_TO_INT(fSizeY, iSizeY); + + return Py_BuildValue("bii", (int)bGet, iSizeX, iSizeY); +} + +PyObject * miniMapAddWayPoint(PyObject * poSelf, PyObject * poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + float fX; + if (!PyTuple_GetFloat(poArgs, 1, &fX)) + return Py_BuildException(); + + float fY; + if (!PyTuple_GetFloat(poArgs, 2, &fY)) + return Py_BuildException(); + + char * buf; + if (!PyTuple_GetString(poArgs, 3, &buf)) + return Py_BuildException(); + + CPythonMiniMap::Instance().AddWayPoint(CPythonMiniMap::TYPE_WAYPOINT, (DWORD)iID, fX, fY, buf); + + return Py_BuildNone(); +} + +PyObject * miniMapRemoveWayPoint(PyObject * poSelf, PyObject * poArgs) +{ + int iID; + if (!PyTuple_GetInteger(poArgs, 0, &iID)) + return Py_BuildException(); + + CPythonMiniMap::Instance().RemoveWayPoint((DWORD)iID); + + return Py_BuildNone(); +} + +PyObject* miniMapRegisterAtlasWindow(PyObject* poSelf, PyObject* poArgs) +{ + PyObject * poHandler; + if (!PyTuple_GetObject(poArgs, 0, &poHandler)) + return Py_BuildException(); + CPythonMiniMap::Instance().RegisterAtlasWindow(poHandler); + return Py_BuildNone(); +} + +PyObject* miniMapUnregisterAtlasWindow(PyObject* poSelf, PyObject* poArgs) +{ + CPythonMiniMap::Instance().UnregisterAtlasWindow(); + return Py_BuildNone(); +} + +PyObject* miniMapGetGuildAreaID(PyObject* poSelf, PyObject* poArgs) +{ + float fx; + if (!PyTuple_GetFloat(poArgs, 0, &fx)) + return Py_BuildException(); + float fy; + if (!PyTuple_GetFloat(poArgs, 1, &fy)) + return Py_BuildException(); + + DWORD dwGuildID = CPythonMiniMap::Instance().GetGuildAreaID(fx, fy); + return Py_BuildValue("i", dwGuildID); +} + +void initMiniMap() +{ + static PyMethodDef s_methods[] = + { + { "SetScale", miniMapSetScale, METH_VARARGS }, + { "ScaleUp", miniMapScaleUp, METH_VARARGS }, + { "ScaleDown", miniMapScaleDown, METH_VARARGS }, + { "SetMiniMapSize", miniMapSetMiniMapSize, METH_VARARGS }, + + { "SetCenterPosition", miniMapSetCenterPosition, METH_VARARGS }, + + { "Destroy", miniMapDestroy, METH_VARARGS }, + { "Create", miniMapCreate, METH_VARARGS }, + { "Update", miniMapUpdate, METH_VARARGS }, + { "Render", miniMapRender, METH_VARARGS }, + + { "Show", miniMapShow, METH_VARARGS }, + { "Hide", miniMapHide, METH_VARARGS }, + + { "isShow", miniMapisShow, METH_VARARGS }, + + { "GetInfo", miniMapGetInfo, METH_VARARGS }, + + { "LoadAtlas", miniMapLoadAtlas, METH_VARARGS }, + { "UpdateAtlas", miniMapUpdateAtlas, METH_VARARGS }, + { "RenderAtlas", miniMapRenderAtlas, METH_VARARGS }, + { "ShowAtlas", miniMapShowAtlas, METH_VARARGS }, + { "HideAtlas", miniMapHideAtlas, METH_VARARGS }, + { "isShowAtlas", miniMapisShowAtlas, METH_VARARGS }, + { "IsAtlas", miniMapIsAtlas, METH_VARARGS }, + { "GetAtlasInfo", miniMapGetAtlasInfo, METH_VARARGS }, + { "GetAtlasSize", miniMapGetAtlasSize, METH_VARARGS }, + + { "AddWayPoint", miniMapAddWayPoint, METH_VARARGS }, + { "RemoveWayPoint", miniMapRemoveWayPoint, METH_VARARGS }, + + { "RegisterAtlasWindow", miniMapRegisterAtlasWindow, METH_VARARGS }, + { "UnregisterAtlasWindow", miniMapUnregisterAtlasWindow, METH_VARARGS }, + + { "GetGuildAreaID", miniMapGetGuildAreaID, METH_VARARGS }, + + { NULL, NULL }, + }; + + PyObject * poModule = Py_InitModule("miniMap", s_methods); + + PyModule_AddIntConstant(poModule, "TYPE_OPC", CPythonMiniMap::TYPE_OPC); + PyModule_AddIntConstant(poModule, "TYPE_OPCPVP", CPythonMiniMap::TYPE_OPCPVP); + PyModule_AddIntConstant(poModule, "TYPE_OPCPVPSELF", CPythonMiniMap::TYPE_OPCPVPSELF); + PyModule_AddIntConstant(poModule, "TYPE_NPC", CPythonMiniMap::TYPE_NPC); + PyModule_AddIntConstant(poModule, "TYPE_MONSTER", CPythonMiniMap::TYPE_MONSTER); + PyModule_AddIntConstant(poModule, "TYPE_WARP", CPythonMiniMap::TYPE_WARP); + PyModule_AddIntConstant(poModule, "TYPE_WAYPOINT", CPythonMiniMap::TYPE_WAYPOINT); + PyModule_AddIntConstant(poModule, "TYPE_PARTY", CPythonMiniMap::TYPE_PARTY); + PyModule_AddIntConstant(poModule, "TYPE_EMPIRE", CPythonMiniMap::TYPE_EMPIRE); +} \ No newline at end of file diff --git a/extension/src/port/UserInterface/StdAfx.h b/extension/src/port/UserInterface/StdAfx.h index c593a2da..e9848b31 100644 --- a/extension/src/port/UserInterface/StdAfx.h +++ b/extension/src/port/UserInterface/StdAfx.h @@ -11,6 +11,7 @@ #include "../GameLib/StdAfx.h" // 40250 PCH order: GameLib types precede UserInterface/GameType.h. #include "../GameLib/RaceData.h" #include "../EterPythonLib/StdAfx.h" +#include "../PRTerrainLib/StdAfx.h" // 40250 PCH: PR_FCNV/PR_ICNV for PR_FLOAT_TO_INT. #include "Locale.h" // Before GameType.h, as in 40250: Locale_inc.h's feature macros shape its tables. #include "GameType.h" // 40250's UserInterface precompiled header supplies these item types. #include "../EterBase/tea.h" @@ -51,6 +52,7 @@ void initItem(); void initNonPlayer(); void initTrade(); void initTextTail(); +void initMiniMap(); void initChat(); void initnet(); void initeffect(); diff --git a/extension/src/port/common/D3DXMath.h b/extension/src/port/common/D3DXMath.h index d6a2f482..eec8d443 100644 --- a/extension/src/port/common/D3DXMath.h +++ b/extension/src/port/common/D3DXMath.h @@ -243,6 +243,14 @@ struct D3DXCOLOR FLOAT r, g, b, a; }; +inline D3DXCOLOR* D3DXColorModulate(D3DXCOLOR* pOut, const D3DXCOLOR* pC1, const D3DXCOLOR* pC2) +{ + pOut->r = pC1->r * pC2->r; + pOut->g = pC1->g * pC2->g; + pOut->b = pC1->b * pC2->b; + pOut->a = pC1->a * pC2->a; + return pOut; +} static_assert(sizeof(D3DXVECTOR2) == 8 && sizeof(D3DXVECTOR3) == 12 && sizeof(D3DXVECTOR4) == 16, "D3DX vector layout"); static_assert(sizeof(D3DXMATRIX) == 64 && sizeof(D3DXQUATERNION) == 16 && sizeof(D3DXCOLOR) == 16, "D3DX layout"); diff --git a/extension/tests/port_login_flow_test.cpp b/extension/tests/port_login_flow_test.cpp index a18abc68..13d9b0ed 100644 --- a/extension/tests/port_login_flow_test.cpp +++ b/extension/tests/port_login_flow_test.cpp @@ -501,6 +501,14 @@ int main(int argc, char** argv) "assert item.GetItemType() == item.ITEM_TYPE_WEAPON and item.GetItemSubType() == item.WEAPON_SWORD\n" "assert item.GetValue(3) > 0, 'min attack'")); + // miniMap module (PythonMiniMapModule.cpp): uiminimap.MiniMap created and showed it. CMapOutdoor is not + // ported, so CMapManager::IsMapOutdoor() is false and the atlas reports "not loaded" as 40250 does off an + // outdoor map. + CHECK(py("import miniMap\n" + "assert miniMap.isShow()\n" + "(bGet, x, y) = miniMap.GetAtlasSize()\n" + "assert not bGet, (bGet, x, y)")); + // Ground items (CPythonItem): the fake server put vnum 19 next to the actor at entergame (GC_ITEM_GROUND_ADD // + GC_ITEM_OWNERSHIP). player.PickCloseItem finds it within __GetPickableDistance, sends CG_ITEM_PICKUP, // and the server's GC_ITEM_GROUND_DEL removes it.