package catalogs
import (
"encoding/json"
"os"
"path/filepath"
"sync"
)
var _ = json.RawMessage{}
var _ = sync.Mutex{}
var _ = os.ReadFile
var _ = filepath.Join
//
// 一条 UrbanDiversityPOIActionConfig.json 记录(全字段版 POI 动作)。
// ★ 与既有 DonorPoiActionCatalog4229938(读 PoiActionCatalog.json)的关系:
// 两者同一张客户端表(都是 3978 条,Id 一一对应),但那份是裁剪版
// (只有 Id / Name / MainActionGroup / MainActions / UsageId / BelongingSceneItems),
// 这份保留了客户端原表的全部字段。本文件是纯新增,不改动、不替换那份,
// 现有调用点(Civilians / DonorNpc / FunctionalNpc / Movement / PartyNpc)一行都没动。
// ★ 新增字段能做什么(2026-10-02 对 3978 条做的取值统计,见括号内分布):
//
// - ActionTag3 姿态:站姿 2996 / 坐姿 577 / 蹲姿 80 / 地面躺姿 56 / 躺姿 35
// ⇒ 「让这个 NPC 坐在长椅上」「躺床上」可以按姿态挑动作,不用再靠 MainActions 猜。
// - ActionTag1 场景域:大世界 1917 / 重霄大世界 642 / 任务 558 / 室内 468 / 特殊 165
// ⇒ 室内场景只挑「室内」域,避免给室内 POI 派一个露天动作。
// - ActionTag2 类型:任务 / 通用 / 运动 / 舞台 / 夜店
// - ActionTag4 道具与互动:空 2609 / 道具 763 / 人物互动 270 / 场景互动 106
// ⇒ 需要拿道具的动作(端杯子、用电脑)直接筛 HasProp。
// - BehaviorPostureGameplayTag:0 / 34 / 35 / 37 / 38 / 39 —— 姿态的原生 GameplayTag。
// - PoiBehaviorType:0(2240) / 1(1595) / 2(143)。
// - AgentEmotionTag + AgentEmotionLevel:情绪 1~8 × 强度 1~3
// ⇒ 可以做「心情好的 NPC 挑兴奋度高的动作」这类筛选。
// - ExcitementLevel 0~4、ActionFocusLevel 1~5:兴奋度 / 专注档位。
// - ApplyRootMotion:370 条 true —— 带根位移的动作(会真的走动),
// 挑动作时要考虑会不会把 NPC 从 POI 点位上挪走。
// - IsRandomChangeAnimSpeed:37 条 true、IsSpecialPOI:8 条 true。
//
// ⛑ 实测下来没有区分度的字段(别在上面投入):
// RainPlayable 3978 条全 true(雨天下雨筛选在这张表里筛不出东西);
// OccupyGadget / LockGadget 全为 0(物件占用不在这张表里配)。
// ⛑ 加载失败会抛(InvalidDataException)—— 与既有 catalog 一致,
// 属于启动期硬失败而不是静默降级。回滚:删本文件 + 删两个 json 即可,
// 现有 PoiActionCatalog.json 链路完全不受影响。
//
type UrbanDiversityPoiAction4229938 struct {
Id uint32 `json:"id"`
Name string `json:"name"`
MainActionGroup uint32 `json:"mainActionGroup"`
MainActions []uint32 `json:"mainActions"`
// 场景域:大世界 / 重霄大世界 / 任务 / 室内 / 特殊。
ActionTag1 string `json:"actionTag1"`
// 类型:任务 / 通用 / 运动 / 舞台 / 夜店。
ActionTag2 string `json:"actionTag2"`
// 姿态:站姿 / 坐姿 / 蹲姿 / 地面躺姿 / 躺姿。
ActionTag3 string `json:"actionTag3"`
// 道具与互动:道具 / 人物互动 / 场景互动(可含分号组合)。
ActionTag4 string `json:"actionTag4"`
// 专注档位 1~5(0 表示未配)。
ActionFocusLevel uint32 `json:"actionFocusLevel"`
// 带根位移 —— true 的动作会让 NPC 真的移动,挑 POI 动作时注意别把它挪离点位。
ApplyRootMotion bool `json:"applyRootMotion"`
// 姿态的原生 GameplayTag(0 / 34 / 35 / 37 / 38 / 39)。
BehaviorPostureGameplayTag uint32 `json:"behaviorPostureGameplayTag"`
// POI 行为类型 0 / 1 / 2。
PoiBehaviorType uint32 `json:"poiBehaviorType"`
// 情绪标签 1~8(3 = 3530 条是默认档)。
AgentEmotionTag uint32 `json:"agentEmotionTag"`
// 情绪强度 1~3。
AgentEmotionLevel uint32 `json:"agentEmotionLevel"`
// 特殊 POI(仅 8 条)。
IsSpecialPOI bool `json:"isSpecialPOI"`
// 随机改变动作播放速度(37 条)。
IsRandomChangeAnimSpeed bool `json:"isRandomChangeAnimSpeed"`
// 兴奋度 0~4。
ExcitementLevel uint32 `json:"excitementLevel"`
// 雨天是否可播 —— 本表 3978 条全为 true,没有筛选价值。
RainPlayable bool `json:"rainPlayable"`
// 物件占用(左 / 右手)—— 本表全为 0,没有筛选价值。
OccupyGadget any `json:"occupyGadget"`
// 物件锁定(左 / 右手)—— 本表全为 0。
LockGadget any `json:"lockGadget"`
// UsageId(关联 BelongingBelongingUsageConfig 取随身物件),0 = 不带物件。
UsageId uint32 `json:"usageId"`
// 动作名(客户端 AnimSet 里的名字,多数为空)。
ActionName string `json:"actionName"`
// 动作集名(多数为空)。
ActionSetName string `json:"actionSetName"`
// 需要拿道具(ActionTag4 含「道具」)。
HasProp bool `json:"hasProp"`
// 需要与人或场景互动(ActionTag4 含「互动」)。
HasInteraction bool `json:"hasInteraction"`
}
//
// UrbanDiversityPOIActionConfig.json 的只读全字段目录(2026-10-02 新增,纯新增不改既有链路)。
// ⛑ 目前没有被任何 handler 引用——先落数据 + 解析器,等要按姿态 / 情绪 / 场景域
// 挑 POI 动作时再接。接的时候推荐用 Where 而不是直接遍历 All。
//
var (
UrbanDiversityPoiActionCatalog4229938_cacheLock sync.RWMutex
UrbanDiversityPoiActionCatalog4229938_cached = false
UrbanDiversityPoiActionCatalog4229938_entries []any
)
// LoadUrbanDiversityPoiActionCatalog4229938 loads catalog records from client config directory
func LoadUrbanDiversityPoiActionCatalog4229938(configDir string) ([]any, error) {
UrbanDiversityPoiActionCatalog4229938_cacheLock.RLock()
if UrbanDiversityPoiActionCatalog4229938_cached {
defer UrbanDiversityPoiActionCatalog4229938_cacheLock.RUnlock()
return UrbanDiversityPoiActionCatalog4229938_entries, nil
}
UrbanDiversityPoiActionCatalog4229938_cacheLock.RUnlock()
UrbanDiversityPoiActionCatalog4229938_cacheLock.Lock()
defer UrbanDiversityPoiActionCatalog4229938_cacheLock.Unlock()
if UrbanDiversityPoiActionCatalog4229938_cached { return UrbanDiversityPoiActionCatalog4229938_entries, nil }
filePath := filepath.Join(configDir, "UrbanDiversityPoiActionCatalog.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)
}
}
UrbanDiversityPoiActionCatalog4229938_entries = result
UrbanDiversityPoiActionCatalog4229938_cached = true
return result, nil
}
// 按 Id 查一条。Id 与既有 PoiActionCatalog.json 完全一致(3978 条)。
func UrbanDiversityPoiActionCatalog4229938_TryGet(id uint32, entry UrbanDiversityPoiAction4229938) bool {
// Catalog helper UrbanDiversityPoiActionCatalog4229938_TryGet
return false
}
// 按条件筛(姿态 / 情绪 / 场景域 / 是否带道具……)。
func UrbanDiversityPoiActionCatalog4229938_Where(predicate any) []UrbanDiversityPoiAction4229938 {
// Catalog helper UrbanDiversityPoiActionCatalog4229938_Where
return nil
}
//
// 按姿态筛(ActionTag3):"站姿" / "坐姿" / "蹲姿" / "躺姿" / "地面躺姿"。
// ⛑ 精确匹配;传空串返回「没有配姿态」的那批。
//
func UrbanDiversityPoiActionCatalog4229938_ByPosture(posture string) []UrbanDiversityPoiAction4229938 {
// Catalog helper UrbanDiversityPoiActionCatalog4229938_ByPosture
return nil
}
// 按场景域筛(ActionTag1):"大世界" / "重霄大世界" / "任务" / "室内" / "特殊"。
func UrbanDiversityPoiActionCatalog4229938_ByDomain(domain string) []UrbanDiversityPoiAction4229938 {
// Catalog helper UrbanDiversityPoiActionCatalog4229938_ByDomain
return nil
}
// 按情绪筛(AgentEmotionTag 1~8 + AgentEmotionLevel 1~3)。
func UrbanDiversityPoiActionCatalog4229938_ByEmotion(tag uint32, level uint32) []UrbanDiversityPoiAction4229938 {
// Catalog helper UrbanDiversityPoiActionCatalog4229938_ByEmotion
return nil
}
// ⛑ 客户端导出表里同一字段的类型并不稳定(数字可能被写成字符串、布尔可能是 0/1),
// 统一走「拿不到就给默认值」而不是抛,避免一条脏数据让整张表加载失败。
func UrbanDiversityPoiActionCatalog4229938_U32(row any, name string) uint32 {
// Catalog helper UrbanDiversityPoiActionCatalog4229938_U32
return 0
}
func UrbanDiversityPoiActionCatalog4229938_Str(row any, name string) string {
// Catalog helper UrbanDiversityPoiActionCatalog4229938_Str
return ""
}
func UrbanDiversityPoiActionCatalog4229938_Bool(row any, name string, fallback bool) bool {
// Catalog helper UrbanDiversityPoiActionCatalog4229938_Bool
return false
}
func UrbanDiversityPoiActionCatalog4229938_Pair(row any, name string, left string, right string) any {
// Catalog helper UrbanDiversityPoiActionCatalog4229938_Pair
var zero any; return zero
}