This repository has been archived on 2026-10-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Ananta-ps/internal/catalogs/party_spot_catalog4229938.go
T

124 lines
4.8 KiB
Go
Raw Normal View History

package catalogs
import (
"encoding/json"
"os"
"path/filepath"
"sync"
)
var _ = json.RawMessage{}
var _ = sync.Mutex{}
var _ = os.ReadFile
var _ = filepath.Join
//
// PartyConfig.json 里的**派对场地**信息(2026-09-26 第 34 轮)。
// WHY THIS FILE EXISTS
// --------------------
// 第 33 轮把「邀请名单」修对之后,用户提出:NPC 不该被塞在玩家身边 2.5 m —— 那是我自己编的
// 站位(「取巧」);**官方在配表里给了规定位置** = `PartySpot` + `PartyRotation`。
// 逐字段核对(ConfigDump_v3\PartyConfig.json,共 7 条):
// <code>
// 13030000 露营(新启) PartySpot=[1288.91003,-0.0900000036,2374.46997] PartyRotation=-76.6750031 MaxNum=3 RaidId=23300888
// 13030002 露营引导 PartySpot=[1276.94995,-0.295366287,2382.59009] PartyRotation=103.629997
// 13030003 舞会 PartySpot=[2574.23999,80.1350021,1271] PartyRotation=91.8000031(另有 DanceSpot/DanceRotation)
// 13030004/13030005 联机 PartySpot=[0,0,0] ← ★「本行没有场地」的哨兵值,必须判掉
// </code>
// ★ `PartySpot` 在客户端两侧都**没有业务消费者**(Lua 侧只有 `ClientConfig.lua` 的字段注册;
// C# metadata 侧只有 `get_PartySpot` / `set_PartySpot` / `&lt;PartySpot&gt;k__BackingField` /
// `PartySpotIndex` 这类**配表访问器**)
// ⇒ 它是**关卡/玩法侧**的场地标记,语义 = 「派对在这里举行」。
// 把它用作**服务端生成 NPC 的落点**,是这个语义最直接的用法,而且**完全由配表驱动**
// (不是我们另编一个坐标)—— 这正是用户要的「把选定的角色放在规定的位置」。
// ⚠ 与服务端其它 catalog 的差异:**本表允许缺失**。
// `DonorNpcCatalog4229938` 在文件缺失时直接抛(它管的是核心 NPC 数据,缺了没得玩);
// 而派对场地只是一个「比玩家身边更正统的落点」—— 缺表时应回退玩家锚点,
// **不能让整个派对功能挂掉**。所以 Load() 全程 try/catch + 返回空表。
// ★ 第 38 轮新增 PartySpotEntry4229938.GamePlayType(配表字段 `GamePlayType`):
// 它把 partyId 映射到 `NpcCultivationGameplayTypeConfig` 的 Id
// (13030000/13030002 → 91055000 露营、13030003 → 91056002 舞会),
// 调用方拿它给这批 NPC 选「预制动作」表(见 GameplaySettings.PartyNpcPoi*)。
// ⚠ 它**独立于** HasUsableSpot —— 联机那两条也有 GamePlayType,只是没有场地。
//
type PartySpotEntry4229938 struct {
Id uint32 `json:"id"`
RaidId uint32 `json:"raidId"`
MaxNum uint32 `json:"maxNum"`
MaxDuration uint32 `json:"maxDuration"`
GamePlayType uint32 `json:"gamePlayType"`
Spot Vec3 `json:"spot"`
Rotation float32 `json:"rotation"`
//
// 配表是否给了**可用**的站位。联机那两条(13030004 / 13030005)写的是 [0,0,0],
// 那是「本行没有场地」的哨兵、不是真的在原点 ⇒ 判掉,让调用方回退。
//
HasUsableSpot bool `json:"hasUsableSpot"`
}
var (
PartySpotCatalog4229938_cacheLock sync.RWMutex
PartySpotCatalog4229938_cached = false
PartySpotCatalog4229938_entries []any
)
// LoadPartySpotCatalog4229938 loads catalog records from client config directory
func LoadPartySpotCatalog4229938(configDir string) ([]any, error) {
PartySpotCatalog4229938_cacheLock.RLock()
if PartySpotCatalog4229938_cached {
defer PartySpotCatalog4229938_cacheLock.RUnlock()
return PartySpotCatalog4229938_entries, nil
}
PartySpotCatalog4229938_cacheLock.RUnlock()
PartySpotCatalog4229938_cacheLock.Lock()
defer PartySpotCatalog4229938_cacheLock.Unlock()
if PartySpotCatalog4229938_cached { return PartySpotCatalog4229938_entries, nil }
filePath := filepath.Join(configDir, "PartySpotCatalog.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)
}
}
PartySpotCatalog4229938_entries = result
PartySpotCatalog4229938_cached = true
return result, nil
}
func PartySpotCatalog4229938_TryGet(partyId uint32, entry PartySpotEntry4229938) bool {
// Catalog helper PartySpotCatalog4229938_TryGet
return false
}
func PartySpotCatalog4229938_U32(row any, name string) uint32 {
// Catalog helper PartySpotCatalog4229938_U32
return 0
}
func PartySpotCatalog4229938_Single(row any, name string) float32 {
// Catalog helper PartySpotCatalog4229938_Single
return 0
}
// 读 [x,y,z];形状不对或含 NaN 就返回零向量(⇒ HasUsableSpot = false)。
func PartySpotCatalog4229938_ReadVector(row any, name string) Vec3 {
// Catalog helper PartySpotCatalog4229938_ReadVector
var zero Vec3; return zero
}