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/npc_activity_catalog4229938.go
T

158 lines
6.1 KiB
Go

package catalogs
import (
"encoding/json"
"os"
"path/filepath"
"sync"
)
var _ = json.RawMessage{}
var _ = sync.Mutex{}
var _ = os.ReadFile
var _ = filepath.Join
// One row of AgentDataSetsActivityConfig — something an NPC can be seen doing.
type NpcActivityEntry4229938 struct {
Id uint32 `json:"id"`
AgentTag uint32 `json:"agentTag"`
NpcCultivationId uint32 `json:"npcCultivationId"`
Raid uint32 `json:"raid"`
Performance string `json:"performance"`
MapName string `json:"mapName"`
X float32 `json:"x"`
Y float32 `json:"y"`
Z float32 `json:"z"`
// Authored rows carry MapPosition; the rest are "临时点位" placeholders with a zero vector.
HasPosition bool `json:"hasPosition"`
}
// What NpcActivityCatalog4229938.Resolve picked, and why — for logs.
type NpcActivityChoice struct {
Entry *NpcActivityEntry4229938 `json:"entry"`
Mode string `json:"mode"`
Timed *NpcActivityEntry4229938 `json:"timed"`
Spot *RosterNpcStaticSpot `json:"spot"`
// 有没有一个能落地的坐标 —— 官方活动坐标,或手工常驻点。
Placeable bool `json:"placeable"`
PlaceX float32 `json:"placeX"`
PlaceY float32 `json:"placeY"`
PlaceZ float32 `json:"placeZ"`
}
//
// Reads Configs/NpcActivityCatalog.json — the server copy of the client's
// AgentDataSetsActivityConfig (284 rows), generated by _gen_npc_life_cfg.py out of
// 补丁和工具\DUMPS\readable_world_dump_4229938_final.zip
// (01_CONFIGS/npc_systems/table/AgentDataSetsActivityConfig.json).
// Why it matters: this is the table that turns "an NPC tag" into "a place and a performance".
// AgentDataSetsActivityCfgId on the agent's sync info is an id into THIS table, and
// MapPosition is where the official build actually puts the character (Richie on the
// treadmill at 1191,0,2052 is just one row). 153 of the 284 rows carry a real position; all of
// them sit in the two open-world raids (23300888 / 23300999).
// The id also reaches the UI: NpcDaliyManager:OnRenderActivity resolves it through the same
// table for the icon/description, and MapSubSystem_SpiritAcquisition reads the schedule's
// RaidId + NpcScheduleInfo.Position to drop the map marker — which is why the login frame's
// FavorNpcDailyScheduleInfos should carry these coordinates too.
//
var (
NpcActivityCatalog4229938_cacheLock sync.RWMutex
NpcActivityCatalog4229938_cached = false
NpcActivityCatalog4229938_entries []any
)
// LoadNpcActivityCatalog4229938 loads catalog records from client config directory
func LoadNpcActivityCatalog4229938(configDir string) ([]any, error) {
NpcActivityCatalog4229938_cacheLock.RLock()
if NpcActivityCatalog4229938_cached {
defer NpcActivityCatalog4229938_cacheLock.RUnlock()
return NpcActivityCatalog4229938_entries, nil
}
NpcActivityCatalog4229938_cacheLock.RUnlock()
NpcActivityCatalog4229938_cacheLock.Lock()
defer NpcActivityCatalog4229938_cacheLock.Unlock()
if NpcActivityCatalog4229938_cached { return NpcActivityCatalog4229938_entries, nil }
filePath := filepath.Join(configDir, "NpcActivityCatalog.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)
}
}
NpcActivityCatalog4229938_entries = result
NpcActivityCatalog4229938_cached = true
return result, nil
}
func NpcActivityCatalog4229938_TryGet(activityId uint32, entry NpcActivityEntry4229938) bool {
// Catalog helper NpcActivityCatalog4229938_TryGet
return false
}
//
// The activity an AgentTag is doing right now, or 0 when that tag has neither a schedule nor
// an authored position (the two protagonists — AgentTag 2/3 — are exactly this case).
//
func NpcActivityCatalog4229938_CurrentFor(agentTag uint32, daySecond int32) *NpcActivityEntry4229938 {
// Catalog helper NpcActivityCatalog4229938_CurrentFor
return nil
}
//
// Same tag, but ignoring the clock: the authored activity with a real position inside
// , lowest Id first. Used when the current time slice
// points at an activity we cannot place — either it has no MapPosition at all (Richie's 05:00
// "给垃圾桶蟹开罚单" is a 临时点位) or it belongs to the other open-world raid.
// Returns null when this tag has nothing placeable in that raid.
// ⛑⛑ Intentionally not "nearest to the player". A player-relative pick is re-evaluated
// every tick, so the answer changes as the player walks and the character appears to follow
// him around; combined with the enter radius it degenerates into "whoever has no schedule
// materialises at your feet". Official data is a fixed spot — pick one deterministically and
// let the enter radius decide whether the player is close enough to see it.
//
func NpcActivityCatalog4229938_FirstPositioned(agentTag uint32, raid uint32) *NpcActivityEntry4229938 {
// Catalog helper NpcActivityCatalog4229938_FirstPositioned
return nil
}
//
// Hand-authored standing spot for a character that has no official daily-life data at all
// (gameplay.rosterNpc.staticSpots). Returns null when this spirit has none, or when the
// spot belongs to a different raid.
//
func NpcActivityCatalog4229938_StaticSpotFor(spiritId uint32, raid uint32) *RosterNpcStaticSpot {
// Catalog helper NpcActivityCatalog4229938_StaticSpotFor
return nil
}
//
// The single selection policy for "what is this character doing right now" — used by both the
// switch-away path and the world roster so the two can never disagree.
// Mode is one of: no-tag / no-schedule / timed /
// fallback-in-raid / no-position / other-raid / static-spot.
// ⛑ no-tag / no-schedule / other-raid / no-position carry a null
// Entry AND a null Spot — the caller must NOT fall back to "stand
// next to the player" or you get 09-25's crowd-at-your-feet bug.
//
func NpcActivityCatalog4229938_Resolve(spiritId uint32, daySecond int32, raid uint32, requirePosition bool, px float32, py float32, pz float32) NpcActivityChoice {
// Catalog helper NpcActivityCatalog4229938_Resolve
var zero NpcActivityChoice; return zero
}