130 lines
4.9 KiB
Go
130 lines
4.9 KiB
Go
package catalogs
|
||
|
||
import (
|
||
"encoding/json"
|
||
"os"
|
||
"path/filepath"
|
||
"sync"
|
||
)
|
||
|
||
var _ = json.RawMessage{}
|
||
var _ = sync.Mutex{}
|
||
var _ = os.ReadFile
|
||
var _ = filepath.Join
|
||
|
||
//
|
||
// PartyDanceSpotConfig.json 里的**舞池点位**(2026-09-26 第 49 轮,舞会线)。
|
||
// WHY THIS FILE EXISTS
|
||
// --------------------
|
||
// 第 48 轮用户两条硬指令:「**舞会有舞会的摆法,不要参考露营**」+「**走官方路径**」。
|
||
// 露营的摆法是「以圆心为心、半径 r 的圆周,人人**朝圆心**」;舞会不是。
|
||
// 官方给舞会单独开了一张表 PartyDanceSpotConfig,字段只有四个:
|
||
// PartyId / MusicId / DanceSpot / DanceRotation。
|
||
// 客户端唯一消费者 ChooseDanceMusicPanelStore.lua:319-332 的用法是
|
||
// Vector3(DanceSpot) + Vector3(0, DanceRotation, 0) 当作
|
||
// **演出 timeline 的世界位姿**(PlayLiveHouseV2 的 timelinePos/timelineRot)
|
||
// ⇒ 语义就是「**舞池在世界的哪里、朝哪边**」。
|
||
// 于是「舞会的摆法」= 站位落在官方 DanceSpot、朝向取官方 DanceRotation
|
||
// (**所有人面向同一个方向**,而不是各自朝圆心)。
|
||
// 逐字段核对(ConfigDump_v3\PartyDanceSpotConfig.json,共 10 条):
|
||
// <code>
|
||
// Id 1~5 PartyId=13030003 新启舞会 MusicId=91131019/20/21/22/23
|
||
// DanceSpot=[2605.33008, 80, 1269.73999] DanceRotation=-84.1142578 ← 五条完全同值
|
||
// Id 6~10 PartyId=13030006 凌云舞会 同名五首
|
||
// DanceSpot=[77.1600037, 19.0752449, -285.609985] DanceRotation=-129.262299
|
||
// </code>
|
||
// ⇒ 按 PartyId 索引即可(同一 party 的五首曲子共用一个舞池);
|
||
// TryGet 保留 MusicId 维度,供将来「一曲一舞池」用。
|
||
// ⚠ 与 PartySpotCatalog4229938 的 PartySpot **不是一个点**,别互相顶替:
|
||
// 13030003 的 PartySpot = [2574.24, 80.135, 1271](场地锚,与
|
||
// PartyCamp.json 的 danceOnly.pos 一致,舞会大门在 2569.63);
|
||
// 而 DanceSpot = [2605.33, 80, 1269.74](舞池,灯光控制台在 2593.94),
|
||
// 两者相距 ≈ 31 m。前者是「场地入口」,后者是「舞池」。
|
||
//
|
||
type PartyDanceSpotEntry4229938 struct {
|
||
Id uint32 `json:"id"`
|
||
PartyId uint32 `json:"partyId"`
|
||
MusicId uint32 `json:"musicId"`
|
||
DanceSpot Vec3 `json:"danceSpot"`
|
||
DanceRotation float32 `json:"danceRotation"`
|
||
//
|
||
// 配表是否给了**可用**的舞池点。[0,0,0] 是哨兵(「本行没有舞池」)不是真原点;
|
||
// 再叠一层有限性检查(NaN/Inf 一律判不可用)⇒ 让调用方回退。
|
||
//
|
||
HasUsableSpot bool `json:"hasUsableSpot"`
|
||
}
|
||
|
||
var (
|
||
PartyDanceSpotCatalog4229938_cacheLock sync.RWMutex
|
||
PartyDanceSpotCatalog4229938_cached = false
|
||
PartyDanceSpotCatalog4229938_entries []any
|
||
)
|
||
|
||
// LoadPartyDanceSpotCatalog4229938 loads catalog records from client config directory
|
||
func LoadPartyDanceSpotCatalog4229938(configDir string) ([]any, error) {
|
||
PartyDanceSpotCatalog4229938_cacheLock.RLock()
|
||
if PartyDanceSpotCatalog4229938_cached {
|
||
defer PartyDanceSpotCatalog4229938_cacheLock.RUnlock()
|
||
return PartyDanceSpotCatalog4229938_entries, nil
|
||
}
|
||
PartyDanceSpotCatalog4229938_cacheLock.RUnlock()
|
||
|
||
PartyDanceSpotCatalog4229938_cacheLock.Lock()
|
||
defer PartyDanceSpotCatalog4229938_cacheLock.Unlock()
|
||
if PartyDanceSpotCatalog4229938_cached { return PartyDanceSpotCatalog4229938_entries, nil }
|
||
|
||
filePath := filepath.Join(configDir, "PartyDanceSpotCatalog.json.json")
|
||
data, err := os.ReadFile(filePath)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
var raw struct {
|
||
Records []json.RawMessage `json:"records"`
|
||
}
|
||
if err := json.Unmarshal(data, &raw); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
var result []any
|
||
for _, item := range raw.Records {
|
||
var m map[string]any
|
||
if err := json.Unmarshal(item, &m); err == nil {
|
||
result = append(result, m)
|
||
}
|
||
}
|
||
|
||
PartyDanceSpotCatalog4229938_entries = result
|
||
PartyDanceSpotCatalog4229938_cached = true
|
||
return result, nil
|
||
}
|
||
|
||
// 按 partyId 取舞池(同一 party 的五首曲子共用一个舞池 ⇒ 取第一条可用行)。
|
||
func PartyDanceSpotCatalog4229938_TryGetByParty(partyId uint32, entry PartyDanceSpotEntry4229938) bool {
|
||
// Catalog helper PartyDanceSpotCatalog4229938_TryGetByParty
|
||
return false
|
||
}
|
||
|
||
// 按 partyId + musicId 精确取(保留维度,当前配表下与 TryGetByParty 同值)。
|
||
func PartyDanceSpotCatalog4229938_TryGet(partyId uint32, musicId uint32, entry PartyDanceSpotEntry4229938) bool {
|
||
// Catalog helper PartyDanceSpotCatalog4229938_TryGet
|
||
return false
|
||
}
|
||
|
||
func PartyDanceSpotCatalog4229938_U32(row any, name string) uint32 {
|
||
// Catalog helper PartyDanceSpotCatalog4229938_U32
|
||
return 0
|
||
}
|
||
|
||
func PartyDanceSpotCatalog4229938_Single(row any, name string) float32 {
|
||
// Catalog helper PartyDanceSpotCatalog4229938_Single
|
||
return 0
|
||
}
|
||
|
||
// 读 [x,y,z];形状不对或含 NaN/Inf 就返回零向量(⇒ HasUsableSpot = false)。
|
||
func PartyDanceSpotCatalog4229938_ReadVector(row any, name string) Vec3 {
|
||
// Catalog helper PartyDanceSpotCatalog4229938_ReadVector
|
||
var zero Vec3; return zero
|
||
}
|
||
|