175 lines
4.0 KiB
Go
175 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"go/format"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
// keep legacy name to avoid breaking nip rules
|
|
var canonicalNameOverridesByID = map[int]string{
|
|
27: "Sabre", // was generated as Saber
|
|
41: "Kris", // was generated as Kriss
|
|
135: "Stiletto", // was generated as Stilleto
|
|
166: "LargeSiegeBow", // was generated as LongSiegeBow
|
|
236: "MithrilPoint", // was generated as MithralPoint
|
|
379: "AncientShield", // was generated as KurastShield (xts)
|
|
417: "DemonHeadShield", // was generated as DemonHead (necro head)
|
|
428: "DemonHead", // was generated as Demonhead (helm)
|
|
157: "QuarterStaff", // was generated as Quarterstaff
|
|
275: "DemonCrossBow", // was generated as DemonCrossbow
|
|
469: "GriffonHeaddress", // was generated as GriffonHeadress
|
|
}
|
|
|
|
func main() {
|
|
if err := run(); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func run() error {
|
|
// Read items.go
|
|
f, err := os.Open("pkg/data/item/items.go")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
nameIDRe := regexp.MustCompile(`Name:\s*"([^"]*)".*\bID:\s*([0-9]+)\b`)
|
|
namesByID := make(map[int]string)
|
|
seenCanonicalRaw := make(map[string]string)
|
|
maxID := -1
|
|
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
m := nameIDRe.FindStringSubmatch(line)
|
|
if m == nil {
|
|
continue
|
|
}
|
|
raw := m[1]
|
|
id, err := strconv.Atoi(m[2])
|
|
if err != nil {
|
|
return fmt.Errorf("parsing item id %q: %w", m[2], err)
|
|
}
|
|
canonical := canonicalizeName(raw)
|
|
if canonical == "" {
|
|
return fmt.Errorf("unable to generate canonical name for item %q", raw)
|
|
}
|
|
if override, ok := canonicalNameOverridesByID[id]; ok {
|
|
canonical = override
|
|
}
|
|
|
|
if existing, exists := namesByID[id]; exists && existing != canonical {
|
|
return fmt.Errorf("item id %d produced inconsistent canonical names %q and %q", id, existing, canonical)
|
|
}
|
|
namesByID[id] = canonical
|
|
key := strings.ToLower(canonical)
|
|
if existingRaw, exists := seenCanonicalRaw[key]; exists && existingRaw != raw {
|
|
return fmt.Errorf("duplicate generated item name %q from %q and %q", canonical, existingRaw, raw)
|
|
}
|
|
if _, exists := seenCanonicalRaw[key]; !exists {
|
|
seenCanonicalRaw[key] = raw
|
|
}
|
|
if id > maxID {
|
|
maxID = id
|
|
}
|
|
}
|
|
if err := scanner.Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if maxID < 0 {
|
|
return fmt.Errorf("no item names found in pkg/data/item/items.go")
|
|
}
|
|
|
|
names := make([]string, maxID+1)
|
|
for id := 0; id <= maxID; id++ {
|
|
name, ok := namesByID[id]
|
|
if !ok {
|
|
return fmt.Errorf("missing item name for id %d in pkg/data/item/items.go", id)
|
|
}
|
|
names[id] = name
|
|
}
|
|
|
|
fmt.Printf("Extracted %d names from items.go\n", len(names))
|
|
|
|
// Write name.go
|
|
var b bytes.Buffer
|
|
b.WriteString(`package item
|
|
|
|
import "strings"
|
|
|
|
const (
|
|
ScrollOfTownPortal = "ScrollOfTownPortal"
|
|
ScrollOfIdentify = "ScrollOfIdentify"
|
|
TomeOfTownPortal = "TomeOfTownPortal"
|
|
TomeOfIdentify = "TomeOfIdentify"
|
|
Key = "Key"
|
|
)
|
|
|
|
func GetNameByEnum(itemNumber uint) Name {
|
|
return Name(Names[itemNumber])
|
|
}
|
|
|
|
func GetIDByName(itemName string) int {
|
|
for i, name := range Names {
|
|
if strings.EqualFold(name, itemName) {
|
|
return i
|
|
}
|
|
}
|
|
|
|
return -1
|
|
}
|
|
|
|
type Name string
|
|
|
|
var Names = []string{
|
|
`)
|
|
for _, n := range names {
|
|
fmt.Fprintf(&b, "\t\"%s\",\n", n)
|
|
}
|
|
b.WriteString("}\n")
|
|
|
|
formatted, err := format.Source(b.Bytes())
|
|
if err != nil {
|
|
return fmt.Errorf("formatting generated name.go: %w", err)
|
|
}
|
|
|
|
if err := os.WriteFile("pkg/data/item/name.go", formatted, 0644); err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Println("Generated name.go successfully")
|
|
return nil
|
|
}
|
|
|
|
func canonicalizeName(raw string) string {
|
|
raw = strings.TrimSpace(raw)
|
|
raw = strings.ReplaceAll(raw, "'", "")
|
|
|
|
var canonical strings.Builder
|
|
capitalizeNext := true
|
|
|
|
for _, r := range raw {
|
|
if unicode.IsLetter(r) || unicode.IsDigit(r) {
|
|
if capitalizeNext && unicode.IsLetter(r) {
|
|
r = unicode.ToUpper(r)
|
|
}
|
|
canonical.WriteRune(r)
|
|
capitalizeNext = false
|
|
continue
|
|
}
|
|
|
|
capitalizeNext = true
|
|
}
|
|
|
|
return canonical.String()
|
|
}
|