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 }