200 lines
9.1 KiB
Go
200 lines
9.1 KiB
Go
package catalogs
|
||||
|
|
|
|||
|
|
import (
|
|||
|
|
"encoding/json"
|
|||
|
|
"os"
|
|||
|
|
"path/filepath"
|
|||
|
|
"sync"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
var _ = json.RawMessage{}
|
|||
|
|
var _ = sync.Mutex{}
|
|||
|
|
var _ = os.ReadFile
|
|||
|
|
var _ = filepath.Join
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
// 一条 UrbanDiversityPOIActionConfig.json 记录(全字段版 POI 动作)。
|
|||
|
|
// <para>★ 与既有 DonorPoiActionCatalog4229938(读 PoiActionCatalog.json)的关系:
|
|||
|
|
// 两者同一张客户端表(都是 3978 条,Id 一一对应),但那份是裁剪版
|
|||
|
|
// (只有 Id / Name / MainActionGroup / MainActions / UsageId / BelongingSceneItems),
|
|||
|
|
// 这份保留了客户端原表的全部字段。本文件是纯新增,不改动、不替换那份,
|
|||
|
|
// 现有调用点(Civilians / DonorNpc / FunctionalNpc / Movement / PartyNpc)一行都没动。</para>
|
|||
|
|
// <para>★ 新增字段能做什么(2026-10-02 对 3978 条做的取值统计,见括号内分布):</para>
|
|||
|
|
// <list type="bullet">
|
|||
|
|
// <item>ActionTag3 姿态:站姿 2996 / 坐姿 577 / 蹲姿 80 / 地面躺姿 56 / 躺姿 35
|
|||
|
|
// ⇒ 「让这个 NPC 坐在长椅上」「躺床上」可以按姿态挑动作,不用再靠 MainActions 猜。</item>
|
|||
|
|
// <item>ActionTag1 场景域:大世界 1917 / 重霄大世界 642 / 任务 558 / 室内 468 / 特殊 165
|
|||
|
|
// ⇒ 室内场景只挑「室内」域,避免给室内 POI 派一个露天动作。</item>
|
|||
|
|
// <item>ActionTag2 类型:任务 / 通用 / 运动 / 舞台 / 夜店</item>
|
|||
|
|
// <item>ActionTag4 道具与互动:空 2609 / 道具 763 / 人物互动 270 / 场景互动 106
|
|||
|
|
// ⇒ 需要拿道具的动作(端杯子、用电脑)直接筛 HasProp。</item>
|
|||
|
|
// <item>BehaviorPostureGameplayTag:0 / 34 / 35 / 37 / 38 / 39 —— 姿态的原生 GameplayTag。</item>
|
|||
|
|
// <item>PoiBehaviorType:0(2240) / 1(1595) / 2(143)。</item>
|
|||
|
|
// <item>AgentEmotionTag + AgentEmotionLevel:情绪 1~8 × 强度 1~3
|
|||
|
|
// ⇒ 可以做「心情好的 NPC 挑兴奋度高的动作」这类筛选。</item>
|
|||
|
|
// <item>ExcitementLevel 0~4、ActionFocusLevel 1~5:兴奋度 / 专注档位。</item>
|
|||
|
|
// <item>ApplyRootMotion:370 条 true —— 带根位移的动作(会真的走动),
|
|||
|
|
// 挑动作时要考虑会不会把 NPC 从 POI 点位上挪走。</item>
|
|||
|
|
// <item>IsRandomChangeAnimSpeed:37 条 true、IsSpecialPOI:8 条 true。</item>
|
|||
|
|
// </list>
|
|||
|
|
// <para>⛑ 实测下来没有区分度的字段(别在上面投入):
|
|||
|
|
// RainPlayable 3978 条全 true(雨天下雨筛选在这张表里筛不出东西);
|
|||
|
|
// OccupyGadget / LockGadget 全为 0(物件占用不在这张表里配)。</para>
|
|||
|
|
// <para>⛑ 加载失败会抛(InvalidDataException)—— 与既有 catalog 一致,
|
|||
|
|
// 属于启动期硬失败而不是静默降级。回滚:删本文件 + 删两个 json 即可,
|
|||
|
|
// 现有 PoiActionCatalog.json 链路完全不受影响。</para>
|
|||
|
|
//
|
|||
|
|
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 新增,纯新增不改既有链路)。
|
|||
|
|
// <para>⛑ 目前没有被任何 handler 引用——先落数据 + 解析器,等要按姿态 / 情绪 / 场景域
|
|||
|
|
// 挑 POI 动作时再接。接的时候推荐用 Where 而不是直接遍历 All。</para>
|
|||
|
|
//
|
|||
|
|
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
|
|||
|
|
}
|
|||
|
|
|