Files
GaCy-GO/internal/common/scene_metadata.go
T

75 lines
2.4 KiB
Go

package common
import (
"encoding/json"
"fmt"
)
// Scene metadata is exported from the installed Client's RuntimeFloor tables.
// A complete group list allows us to exclude deleted/client-owned groups
// without maintaining special cases for individual maps or group IDs.
type sceneMetadata struct {
ClientVersion string `json:"client_version"`
Floors map[uint32]struct {
StartAnchor *AnchorItem `json:"start_anchor"`
Monsters map[uint32]map[uint32]TeleportInfo `json:"monsters"`
GroupCount int `json:"group_count"`
Groups map[uint32]struct {
LoadSide string `json:"load_side"`
Deleted bool `json:"is_deleted"`
} `json:"groups"`
} `json:"floors"`
}
func applySceneMetadata(res *JsonConfig) {
raw, err := ReadResourceFile("resources/SceneMetadata.json")
if err != nil {
return
}
var metadata sceneMetadata
if err := json.Unmarshal(raw, &metadata); err != nil {
LogInfo("[SCENE] Invalid SceneMetadata: %v", err)
return
}
config, err := LoadRuntimeConfig()
if err != nil || metadata.ClientVersion != config.ClientVersion {
LogInfo("[SCENE] SceneMetadata Client revision does not match runtime config; not applied")
return
}
for entryID, configs := range res.LevelOutputConfigs {
for name, scene := range configs {
var planeID, floorID uint32
if n, _ := fmt.Sscanf(name, "P%d_F%d", &planeID, &floorID); n != 2 {
continue
}
floor, ok := metadata.Floors[floorID]
if !ok {
continue
}
if floor.GroupCount == 0 || len(floor.Groups) != floor.GroupCount {
LogInfo("[SCENE] Incomplete group metadata for floor %d; not applied", floorID)
continue
}
if floor.StartAnchor != nil {
res.SceneAnchors[entryID] = []AnchorItem{*floor.StartAnchor}
}
for groupID := range scene.Scenes {
group, exists := floor.Groups[groupID]
if !exists || group.Deleted || group.LoadSide == "Client" {
delete(scene.Scenes, groupID)
LogInfo("[SCENE] Excluded group entry=%d floor=%d group=%d present=%t deleted=%t side=%s", entryID, floorID, groupID, exists, group.Deleted, group.LoadSide)
continue
}
data := scene.Scenes[groupID]
for index := range data.Monsters {
monster := &data.Monsters[index]
if placement, ok := floor.Monsters[groupID][monster.InstID]; ok {
monster.Pos, monster.Rot = placement.Pos, placement.Rot
}
}
scene.Scenes[groupID] = data
}
}
}
}