105 lines
3.3 KiB
Go
105 lines
3.3 KiB
Go
package catalogs
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
)
|
|
|
|
var _ = json.RawMessage{}
|
|
var _ = sync.Mutex{}
|
|
var _ = os.ReadFile
|
|
var _ = filepath.Join
|
|
|
|
//
|
|
// One place the player can invade: an enemy faction's influence area, with the world position of
|
|
// the event that belongs to it.
|
|
//
|
|
//
|
|
// Data comes from three official tables joined offline (_build_invasion_spots.py):
|
|
// FactionInfluenceAreaConfig — the turf itself, and whether it is invadable at all
|
|
// (CanInvasionArea; the player's own turf 犬魔社 is not);
|
|
// FactionInfluenceEventConfig — what sits on that turf (HQ / Camp / Kingpin / Skirmish);
|
|
// TaskEventConfig.CenterPos — where it actually is.
|
|
// ⛑ Three rows are HQ (type=1) and their CenterPos is (0,0,0) in the official data — those
|
|
// are not teleport targets. HasPosition exists so callers can skip them instead of
|
|
// walking the player to the origin.
|
|
//
|
|
type FactionInvasionSpot4229938 struct {
|
|
EventId int32 `json:"eventId"`
|
|
AreaId int32 `json:"areaId"`
|
|
AreaName string `json:"areaName"`
|
|
EventName string `json:"eventName"`
|
|
Type int32 `json:"type"`
|
|
TypeName string `json:"typeName"`
|
|
FactionId uint32 `json:"factionId"`
|
|
Raid uint32 `json:"raid"`
|
|
X float32 `json:"x"`
|
|
Y float32 `json:"y"`
|
|
Z float32 `json:"z"`
|
|
HasPosition bool `json:"hasPosition"`
|
|
}
|
|
|
|
//
|
|
// Reads Configs/FactionInvasionSpots.json. Parsed once behind a Lazy{T}; a
|
|
// missing or malformed file is not fatal — the catalog goes empty and LoadError
|
|
// explains why so the panel can say so.
|
|
//
|
|
var (
|
|
FactionInvasionSpotCatalog4229938_cacheLock sync.RWMutex
|
|
FactionInvasionSpotCatalog4229938_cached = false
|
|
FactionInvasionSpotCatalog4229938_entries []any
|
|
)
|
|
|
|
// LoadFactionInvasionSpotCatalog4229938 loads catalog records from client config directory
|
|
func LoadFactionInvasionSpotCatalog4229938(configDir string) ([]any, error) {
|
|
FactionInvasionSpotCatalog4229938_cacheLock.RLock()
|
|
if FactionInvasionSpotCatalog4229938_cached {
|
|
defer FactionInvasionSpotCatalog4229938_cacheLock.RUnlock()
|
|
return FactionInvasionSpotCatalog4229938_entries, nil
|
|
}
|
|
FactionInvasionSpotCatalog4229938_cacheLock.RUnlock()
|
|
|
|
FactionInvasionSpotCatalog4229938_cacheLock.Lock()
|
|
defer FactionInvasionSpotCatalog4229938_cacheLock.Unlock()
|
|
if FactionInvasionSpotCatalog4229938_cached { return FactionInvasionSpotCatalog4229938_entries, nil }
|
|
|
|
filePath := filepath.Join(configDir, "FactionInvasionSpotCatalog.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)
|
|
}
|
|
}
|
|
|
|
FactionInvasionSpotCatalog4229938_entries = result
|
|
FactionInvasionSpotCatalog4229938_cached = true
|
|
return result, nil
|
|
}
|
|
|
|
// Every spot that has a real world position, ordered by area then event.
|
|
func FactionInvasionSpotCatalog4229938_Placeable() []FactionInvasionSpot4229938 {
|
|
// Catalog helper FactionInvasionSpotCatalog4229938_Placeable
|
|
return nil
|
|
}
|
|
|
|
func FactionInvasionSpotCatalog4229938_ByEventId(eventId int32) *FactionInvasionSpot4229938 {
|
|
// Catalog helper FactionInvasionSpotCatalog4229938_ByEventId
|
|
return nil
|
|
}
|
|
|