Files
bl/common/data/Element/data.go

129 lines
3.1 KiB
Go
Raw Normal View History

package element
2026-04-29 04:53:26 +08:00
import (
_ "embed"
"encoding/json"
"fmt"
"strings"
)
//go:embed data/skillTypes.json
var skillTypesJSON []byte
//go:embed data/typesRelation.json
var typesRelationJSON []byte
type skillTypesFile struct {
Root struct {
Item []skillTypeItem `json:"item"`
} `json:"root"`
}
type skillTypeItem struct {
ID int `json:"id"`
CN string `json:"cn"`
Att string `json:"att"`
IsDou int `json:"is_dou"`
EN []string `json:"en"`
}
type typeRelationFile struct {
Root struct {
Relation []typeRelationItem `json:"relation"`
} `json:"root"`
}
type typeRelationItem struct {
Type string `json:"type"`
Opponent []typeRelationOpponent `json:"opponent"`
}
type typeRelationOpponent struct {
Type string `json:"type"`
Multiple float64 `json:"multiple"`
}
// 初始化全属性克制矩阵。数据来自 seer-types-relation默认关系为 1.0。
func initFullTableMatrix() {
for i := 0; i < maxMatrixSize; i++ {
for j := 0; j < maxMatrixSize; j++ {
matrix[i][j] = 1.0
}
}
2026-04-29 04:53:26 +08:00
enToID := initSkillTypes()
initTypeRelations(enToID)
}
2026-04-29 04:53:26 +08:00
func initSkillTypes() map[string]int {
var cfg skillTypesFile
mustUnmarshalJSON(skillTypesJSON, &cfg, "skillTypes.json")
2026-04-29 04:53:26 +08:00
enToID := make(map[string]int, len(cfg.Root.Item))
for _, item := range cfg.Root.Item {
mustValidElementID(item.ID, "skill type")
if len(item.EN) == 0 {
panic(fmt.Sprintf("skill type %d has no en name", item.ID))
}
2026-04-29 04:53:26 +08:00
elementNameMap[item.ID] = strings.ToUpper(strings.Join(item.EN, "_"))
if item.IsDou == 0 {
validSingleElementIDs[item.ID] = true
enToID[item.EN[0]] = item.ID
}
}
2026-04-29 04:53:26 +08:00
for _, item := range cfg.Root.Item {
if item.IsDou == 0 {
continue
}
2026-04-29 04:53:26 +08:00
if len(item.EN) != 2 {
panic(fmt.Sprintf("dual skill type %d must have two en names", item.ID))
}
primaryID, ok := enToID[item.EN[0]]
if !ok {
panic(fmt.Sprintf("dual skill type %d references unknown primary type %q", item.ID, item.EN[0]))
}
secondaryID, ok := enToID[item.EN[1]]
if !ok {
panic(fmt.Sprintf("dual skill type %d references unknown secondary type %q", item.ID, item.EN[1]))
}
dualElementMap[item.ID] = [2]int{primaryID, secondaryID}
}
2026-04-29 04:53:26 +08:00
return enToID
}
2026-04-29 04:53:26 +08:00
func initTypeRelations(enToID map[string]int) {
var cfg typeRelationFile
mustUnmarshalJSON(typesRelationJSON, &cfg, "typesRelation.json")
2026-04-29 04:53:26 +08:00
for _, relation := range cfg.Root.Relation {
attackerID, ok := enToID[relation.Type]
if !ok {
panic(fmt.Sprintf("type relation references unknown attacker type %q", relation.Type))
}
2026-04-29 04:53:26 +08:00
for _, opponent := range relation.Opponent {
defenderID, ok := enToID[opponent.Type]
if !ok {
panic(fmt.Sprintf("type relation references unknown defender type %q", opponent.Type))
}
matrix[attackerID][defenderID] = opponent.Multiple
}
}
}
2026-04-29 04:53:26 +08:00
func mustUnmarshalJSON(data []byte, target any, name string) {
if err := json.Unmarshal(data, target); err != nil {
panic(fmt.Sprintf("parse %s: %v", name, err))
}
}
2026-04-29 04:53:26 +08:00
func mustValidElementID(id int, kind string) {
if id <= 0 || id >= maxMatrixSize {
panic(fmt.Sprintf("%s id out of range: %d", kind, id))
}
}