92 lines
3.1 KiB
Go
92 lines
3.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 faction (阵营), projected from FactionConfig.json. Rows without a name or without a
|
|
// reputation ladder are excluded at projection time (see _gen_faction_cfg.py).
|
|
// MaxDispositionLevel is the faction's own ceiling from FactionConfig. It is the
|
|
// only value any consumer looks at, and higher is strictly better:
|
|
// NPCShopPanelStore.lua:473/479 DispositionLevel -> shop attitude shown to the player
|
|
// DeliverGiftsPanelStore.lua:512 level > 6 -> favour x1.4, level > 5 -> x1.2
|
|
// SwapCharacterListPanelStore.lua:543 DispositionLevel below the limit locks the character out
|
|
// ClientUtils.lua:614 GetFameLevel returns it, falling back to 999 when the row is missing
|
|
// MaxDisposition is the raw Disposition value that matches that level in
|
|
// FactionDispositionConfig (5 = Reverence = 2100). The map overlays read it alongside the
|
|
// level, so both are stamped together instead of leaving the raw value at zero.
|
|
// Influence / GreetCount / InteractionCount stay at their defaults: they are progress counters
|
|
// for territory control and repeated NPC contact, and inventing values there would misreport
|
|
// how much the player has actually played.
|
|
//
|
|
type FactionEntry4229938 struct {
|
|
Id uint32 `json:"id"`
|
|
Name string `json:"name"`
|
|
MaxDispositionLevel uint32 `json:"maxDispositionLevel"`
|
|
MaxDisposition int32 `json:"maxDisposition"`
|
|
CountryId uint32 `json:"countryId"`
|
|
}
|
|
|
|
//
|
|
// Build-4229938 faction catalog, read from the configured client-data directory. The source
|
|
// table does not ship in the v0.3 Configs folder; it comes from the client config dump.
|
|
// Regenerate with _gen_faction_cfg.py.
|
|
// The client really does read this out of the login payload:
|
|
// lua/LX6/Data/Player/PlayerData/PlayerInfoAchievementData.lua
|
|
// InitPlayerInfo -> info.InfoAchievement.FactionInfoDic -> bindData.FactionInfoDic
|
|
//
|
|
var (
|
|
FactionCatalog4229938_cacheLock sync.RWMutex
|
|
FactionCatalog4229938_cached = false
|
|
FactionCatalog4229938_entries []any
|
|
)
|
|
|
|
// LoadFactionCatalog4229938 loads catalog records from client config directory
|
|
func LoadFactionCatalog4229938(configDir string) ([]any, error) {
|
|
FactionCatalog4229938_cacheLock.RLock()
|
|
if FactionCatalog4229938_cached {
|
|
defer FactionCatalog4229938_cacheLock.RUnlock()
|
|
return FactionCatalog4229938_entries, nil
|
|
}
|
|
FactionCatalog4229938_cacheLock.RUnlock()
|
|
|
|
FactionCatalog4229938_cacheLock.Lock()
|
|
defer FactionCatalog4229938_cacheLock.Unlock()
|
|
if FactionCatalog4229938_cached { return FactionCatalog4229938_entries, nil }
|
|
|
|
filePath := filepath.Join(configDir, "FactionCatalog.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)
|
|
}
|
|
}
|
|
|
|
FactionCatalog4229938_entries = result
|
|
FactionCatalog4229938_cached = true
|
|
return result, nil
|
|
}
|
|
|