fix(automap): 小地图(Automap/Minimap)没有随着大地图区域切换而同步切换 #549
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
问题描述
当玩家在同一幕(Act)内跨区域切换地图时(例如从
areaId=1罗格营地走到areaId=2鲜血荒地、进入areaId=8邪恶洞穴等地下城入口、使用传送门 Town Portal 或同幕传送站 Waypoint),主视角大地图(ClientWorldSceneSource/LevelView)已根据玩家世界坐标实时切换到新区域,但小地图(AutomapView/Minimap)仍然停留在初始0x03 LoadAct所在的旧区域,导致小地图名称、地形层、碰撞网格与玩家当前所在大地图不一致。1.13c Ground Truth (
D2Client.dll)0x03 LoadAct(0x6FB5DB50) 仅在进入游戏或跨幕时发送;同幕跨区域移动/传送仅下发0x07 AddRoomData(RoomReveal) 与玩家位置更新(0x15/0x95/ 移动包)。AUTOMAP_UpdateVisibility(0x6FB10CF0) 每帧根据玩家当前所在 Room 所属的pLevel->dwLevelNo判断区域切换,一旦dwLevelNo变化即调用InitAutomapLayer(dwLevelNo)切换小地图层级并保留同幕已探索 Room 记录。根因分析
OnlineSession.handleServerEvent仅在LoadAct时调用this.automapView.setContext(...),且ClientWorld.apply仅在this.areaId === 0时从RoomReveal初始化areaId,导致同幕切换区域时automapView.currentAreaId与world.areaId停留在旧区域。renderSceneSourceFrame(src/client/scene/world-renderer.ts) 在构建minimapLevel时未将ctx.automapView同步到当前激活的levelView,直接取旧区域的buildMinimapLevel()数据并覆盖了新区域的isoOriginX/Y,造成坐标系错位。Minimap.render(src/client/ui/minimap.ts) 在level.key切换时未重置手动平移偏移量(panX/panY)。修复方案
AutomapView中新增syncActiveLevel(areaId, levelView),在同幕切换区域时更新currentAreaId与缓存的LevelView,同时保留当前(mapSeed, difficulty)下各区域已探索的 Room 状态。OnlineSession中根据玩家实时解析出的levelView.areaId同步更新world.areaId、automapView.syncActiveLevel、soundService.onEnterArea与hudModel。world-renderer.ts的renderSceneSourceFrame中同步ctx.automapView并传入当前levelView.areaId构建小地图数据。Minimap.render中检测到level.key变化时自动调用resetPan()。已在 commit
102d001(合并至main47d18fc)完成修复并合入主干:修复内容
AutomapView.syncActiveLevel(src/client/automap/automap-view.ts):syncActiveLevel(areaId, existingLevelView),在同一局游戏/同一mapSeed内切换区域时同步更新currentAreaId与currentActId并缓存LevelView,同时保留已探索的serverRevealedRooms(0x07)与跨区域缓存。buildMinimapLevel(lang, areaId?)支持直接接收目标areaId,直接使用LevelView的真实网格尺寸(cellsX/cellsY/blocked/isoOriginX/isoOriginY),并合并view.entrances的跨区域出口标记。OnlineSession.syncActiveAreaFromPlayerPosition(src/client/session/online-session.ts):knownAreaIds(记录LoadAct初始区域与所有0x07 RoomReveal区域),在handleServerEvent、tick与sceneSource中基于玩家当前世界子瓦片坐标动态解析所在LevelView。0x03 LoadAct,立即同步更新world.areaId、automapView.syncActiveLevel、soundService.onEnterArea与hudModel.syncFromWorld。renderSceneSourceFrame&Minimap(src/client/scene/world-renderer.ts,src/client/ui/minimap.ts):ctx.automapView与当前大地图levelView/snapshot.levelId对齐。Minimap.draw在level.key切换时自动调用resetPan()重置手动平移偏移。CommandMapper.startLocalPathPrediction(src/client/input/command-mapper.ts):mapService.findLevelViewAtWorldSubTile解析玩家当前所在区域的LevelView,避免邻近区域0x07预揭示覆盖getActiveLevelView()导致本地寻路越界。tests/client/minimap-level-switch-549.test.ts):Area 1 -> Area 2 -> Area 8 -> Area 1无LoadAct连续区域切换、renderSceneSourceFrame+Minimap渲染管线同步与手动平移重置、以及CommandMapper邻近区域预揭示下的本地寻路。