Files
nuzlocke-tracker/tools/fetch-pokeapi/text.go
Julian Tabel 0bf628157f Add Go-based PokeAPI fetch tool
Replaces the Python fetch_pokeapi.py script with a Go tool that crawls
a local PokeAPI instance and writes seed JSON files. Supports caching
and special encounter definitions via JSON config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 19:44:05 +01:00

115 lines
3.6 KiB
Go

package main
import (
"fmt"
"strings"
)
var regionPrefixes = []string{
"kanto-", "johto-", "hoenn-", "sinnoh-",
"unova-", "kalos-", "alola-", "galar-",
}
// CleanLocationName converts a PokeAPI location slug to a clean display name.
// e.g. "kanto-route-1" -> "Route 1", "pallet-town" -> "Pallet Town"
func CleanLocationName(name string) string {
for _, prefix := range regionPrefixes {
if strings.HasPrefix(name, prefix) {
name = name[len(prefix):]
break
}
}
name = strings.ReplaceAll(name, "-", " ")
name = strings.Title(name) //nolint:staticcheck
return name
}
// CleanAreaName extracts a meaningful area suffix, or empty string if it's the default area.
func CleanAreaName(areaName, locationName string) string {
if strings.HasPrefix(areaName, locationName) {
suffix := strings.TrimPrefix(areaName, locationName)
suffix = strings.Trim(suffix, "- ")
if suffix == "" || suffix == "area" {
return ""
}
suffix = strings.ReplaceAll(suffix, "-", " ")
return strings.Title(suffix) //nolint:staticcheck
}
result := strings.ReplaceAll(areaName, "-", " ")
return strings.Title(result) //nolint:staticcheck
}
// FormatFormName converts a PokeAPI pokemon form name to a display name.
// e.g. "rattata-alola" (species: "rattata") -> "Rattata (Alola)"
func FormatFormName(fullName, speciesName string) string {
if strings.HasPrefix(fullName, speciesName+"-") {
formSuffix := fullName[len(speciesName)+1:]
base := toTitleCase(speciesName)
suffix := toTitleCase(formSuffix)
return fmt.Sprintf("%s (%s)", base, suffix)
}
return toTitleCase(fullName)
}
// toTitleCase converts a hyphenated slug to Title Case with spaces.
func toTitleCase(s string) string {
s = strings.ReplaceAll(s, "-", " ")
return strings.Title(s) //nolint:staticcheck
}
// CollectEvolutionConditions extracts human-readable condition strings from an EvolutionDetail.
func CollectEvolutionConditions(detail EvolutionDetail) []string {
var conditions []string
if detail.MinHappiness != nil {
conditions = append(conditions, fmt.Sprintf("happiness >= %d", *detail.MinHappiness))
}
if detail.MinAffection != nil {
conditions = append(conditions, fmt.Sprintf("affection >= %d", *detail.MinAffection))
}
if detail.MinBeauty != nil {
conditions = append(conditions, fmt.Sprintf("beauty >= %d", *detail.MinBeauty))
}
if detail.TimeOfDay != "" {
conditions = append(conditions, detail.TimeOfDay)
}
if detail.KnownMove != nil {
conditions = append(conditions, fmt.Sprintf("knows %s", detail.KnownMove.Name))
}
if detail.KnownMoveType != nil {
conditions = append(conditions, fmt.Sprintf("knows %s-type move", detail.KnownMoveType.Name))
}
if detail.Location != nil {
conditions = append(conditions, fmt.Sprintf("at %s", detail.Location.Name))
}
if detail.PartySpecies != nil {
conditions = append(conditions, fmt.Sprintf("with %s in party", detail.PartySpecies.Name))
}
if detail.PartyType != nil {
conditions = append(conditions, fmt.Sprintf("with %s-type in party", detail.PartyType.Name))
}
if detail.Gender != nil {
if *detail.Gender == 1 {
conditions = append(conditions, "female")
} else {
conditions = append(conditions, "male")
}
}
if detail.NeedsOverworldRain {
conditions = append(conditions, "raining")
}
if detail.TurnUpsideDown {
conditions = append(conditions, "turn upside down")
}
if detail.TradeSpecies != nil {
conditions = append(conditions, fmt.Sprintf("trade for %s", detail.TradeSpecies.Name))
}
if detail.RelativePhysicalStats != nil {
statMap := map[int]string{1: "atk > def", -1: "atk < def", 0: "atk = def"}
if s, ok := statMap[*detail.RelativePhysicalStats]; ok {
conditions = append(conditions, s)
}
}
return conditions
}