fix(scene): unlock teleport pillars on maps missing from mapDefaultEntranceMap
The user report: pillars visible on the map but locked, and clicking a teleport does nothing (client never sends EnterScene). Root cause: mapDefaultEntranceMap covers only 115 of 371 floors - the GetSceneMapInfo reply had no unlocked teleports for the missing floors (mostly new-region 2xxxxx maps), so the client locked the pillars and never initiated the teleport. - findEntryForFloor: resolve entry by searching config names P*_F<floor> directly, with mapDefaultEntranceMap as the first chance - GetSceneMapInfo: use the new resolver and merge teleports.json keys into unlocked_teleport_list for every floor - EnterScene: floor ids resolve through the same path; a teleport id arriving via scene_identifier (MDAIDPPKOPO.PLIDNBMCIJH) now also resolves the destination entry - loadScene: exact teleport position from teleports.json when the res config has no inline teleport with that id
This commit is contained in:
1 parent
72861c3028
commit
d364b9616f
4 files changed
+90
-12
No files matched your search
@@ -120,12 +120,18 @@ func init() {
|
||||
switch {
|
||||
case req.EntryId != 0 && mapHasEntry(res, req.EntryId):
|
||||
resolvedEntry = req.EntryId
|
||||
case sceneIdent != nil && res.MapDefaultEntranceMap[sceneIdent.FloorId] != 0:
|
||||
resolvedEntry = res.MapDefaultEntranceMap[sceneIdent.FloorId]
|
||||
case res.MapDefaultEntranceMap[req.EntryId] != 0:
|
||||
resolvedEntry = res.MapDefaultEntranceMap[req.EntryId]
|
||||
case sceneIdent != nil && sceneIdent.FloorId != 0:
|
||||
resolvedEntry = findEntryForFloor(res, sceneIdent.FloorId)
|
||||
case req.EntryId != 0 && findEntryForFloor(res, req.EntryId) != 0:
|
||||
// req.EntryId doubles as a floor id in some map flows
|
||||
resolvedEntry = findEntryForFloor(res, req.EntryId)
|
||||
case req.TeleportId != 0:
|
||||
resolvedEntry = findEntryByTeleport(res, req.TeleportId, currentEntry())
|
||||
case sceneIdent != nil && sceneIdent.TeleportNigger != nil:
|
||||
if t, okc := sceneIdent.TeleportNigger.(*goproto.SceneIdentifier_MDAIDPPKOPO); okc && t.MDAIDPPKOPO != nil && t.MDAIDPPKOPO.PLIDNBMCIJH != 0 {
|
||||
// map teleport click: teleport id arrives via scene_identifier
|
||||
resolvedEntry = findEntryByTeleport(res, t.MDAIDPPKOPO.PLIDNBMCIJH, currentEntry())
|
||||
}
|
||||
case interactID != 0:
|
||||
resolvedEntry = findEntryByInteract(res, interactID, currentEntry())
|
||||
default:
|
||||
@@ -233,7 +239,10 @@ func init() {
|
||||
&goproto.ChestInfo{ChestType: goproto.ChestType_MAP_INFO_CHEST_TYPE_PUZZLE},
|
||||
)
|
||||
|
||||
if entryID := res.MapDefaultEntranceMap[floorID]; entryID != 0 {
|
||||
// resolve the floor's entry directly (mapDefaultEntranceMap covers
|
||||
// only 115/371 floors - new-region maps were left with no unlocked
|
||||
// teleports, which locked the pillars)
|
||||
if entryID := findEntryForFloor(res, floorID); entryID != 0 {
|
||||
if _, cfg, ok := firstSceneOfEntry(res, entryID); ok {
|
||||
groupIDs := sortedU32Keys2(cfg.Scenes)
|
||||
for _, groupID := range groupIDs {
|
||||
@@ -258,6 +267,20 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// teleports.json covers every map (incl. floors whose res config
|
||||
// has no inline teleports)
|
||||
if m := common.Teleports()[floorID]; m != nil {
|
||||
seen := map[uint32]bool{}
|
||||
for _, t := range mapInfo.UnlockedTeleportList {
|
||||
seen[t] = true
|
||||
}
|
||||
for id := range m {
|
||||
if id != 0 && !seen[id] {
|
||||
mapInfo.UnlockedTeleportList = append(mapInfo.UnlockedTeleportList, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rsp.SceneMapInfo = append(rsp.SceneMapInfo, mapInfo)
|
||||
}
|
||||
return nil
|
||||
@@ -366,12 +389,40 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
// findEntryForFloor resolves an entry id for a floor WITHOUT relying on
|
||||
// mapDefaultEntranceMap (which misses 287/371 floors): search the config
|
||||
// names "P<plane>_F<floor>" directly.
|
||||
func findEntryForFloor(res *common.JsonConfig, floorID uint32) uint32 {
|
||||
if entryID := res.MapDefaultEntranceMap[floorID]; entryID != 0 {
|
||||
return entryID
|
||||
}
|
||||
suffix := fmt.Sprintf("_F%d", floorID)
|
||||
entryIDs := sortedU32Keys2(res.LevelOutputConfigs)
|
||||
for _, eid := range entryIDs {
|
||||
for name := range res.LevelOutputConfigs[eid] {
|
||||
if len(name) > len(suffix) && name[len(name)-len(suffix):] == suffix {
|
||||
return eid
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func mapHasEntry(res *common.JsonConfig, entryID uint32) bool {
|
||||
_, ok := res.LevelOutputConfigs[entryID]
|
||||
return ok
|
||||
}
|
||||
|
||||
func findEntryByTeleport(res *common.JsonConfig, teleportID uint32, fallback uint32) uint32 {
|
||||
// teleports.json covers floors whose res config has no inline teleports:
|
||||
// teleport id -> floor -> entry (via the floor name search)
|
||||
for floorID, m := range common.Teleports() {
|
||||
if _, ok := m[teleportID]; ok {
|
||||
if entry := findEntryForFloor(res, floorID); entry != 0 {
|
||||
return entry
|
||||
}
|
||||
}
|
||||
}
|
||||
entryIDs := sortedU32Keys2(res.LevelOutputConfigs)
|
||||
for _, eid := range entryIDs {
|
||||
names := make([]string, 0, len(res.LevelOutputConfigs[eid]))
|
||||
@@ -459,6 +510,16 @@ func loadScene(s *Session, entryID uint32, isEnterScene bool, teleportID *uint32
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
// exact teleport from teleports.json (covers floors whose res
|
||||
// config has no inline teleports)
|
||||
if m := common.Teleports()[floorID]; m != nil {
|
||||
if tp, ok := m[*teleportID]; ok {
|
||||
jsonPos.X, jsonPos.Y, jsonPos.Z, jsonPos.RotY = tp.Pos.X, tp.Pos.Y, tp.Pos.Z, tp.Rot.Y
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found && len(groupIDs) > 0 {
|
||||
// first teleport of the first group that has one
|
||||
for _, gid := range groupIDs {
|
||||
|
||||
Reference in new issue
Block a user