cmd/horsebot: move to here

This commit is contained in:
2026-02-10 14:03:41 -05:00
parent a534975601
commit c00d3d0186
9 changed files with 567 additions and 6 deletions

148
cmd/horsebot/skill.go Normal file
View File

@@ -0,0 +1,148 @@
package main
import (
"fmt"
"strings"
"sync"
"github.com/disgoorg/disgo/discord"
"git.sunturtle.xyz/zephyr/horse/cmd/horsebot/autocomplete"
"git.sunturtle.xyz/zephyr/horse/horse"
"git.sunturtle.xyz/zephyr/horse/horse/global"
)
func RenderSkill(id horse.SkillID, all map[horse.SkillID]horse.Skill, groups map[int32][4]horse.SkillID) discord.ContainerComponent {
s, ok := all[id]
if !ok {
return discord.NewContainer(discord.NewTextDisplayf("invalid skill ID %v made it to RenderSkill", id))
}
thumburl := fmt.Sprintf("https://gametora.com/images/umamusume/skill_icons/utx_ico_skill_%d.png", s.IconID)
top := "## " + s.Name
if s.UniqueOwner != "" {
top += "\n-# " + s.UniqueOwner
}
r := discord.NewContainer(
discord.NewSection(
discord.NewTextDisplay(top),
discord.NewTextDisplay(s.Description),
).WithAccessory(discord.NewThumbnail(thumburl)),
)
var skilltype string
switch {
case s.Rarity == 3, s.Rarity == 4, s.Rarity == 5:
// unique of various star levels
r.AccentColor = 0xaca4d4
skilltype = "Unique Skill"
case s.UniqueOwner != "":
r.AccentColor = 0xcccccc
skilltype = "Inherited Unique"
case s.Rarity == 2:
// rare (gold)
r.AccentColor = 0xd7c25b
skilltype = "Rare Skill"
case s.GroupRate == -1:
// negative (purple) skill
r.AccentColor = 0x9151d4
skilltype = "Negative Skill"
case !s.WitCheck:
// should be passive (green)
r.AccentColor = 0x66ae1c
skilltype = "Passive Skill"
case isDebuff(s):
// debuff (red)
r.AccentColor = 0xe34747
skilltype = "Debuff Skill"
case s.Rarity == 1:
// common (white)
r.AccentColor = 0xcccccc
skilltype = "Common Skill"
}
r.Components = append(r.Components, discord.NewSmallSeparator())
text := make([]string, 0, 3)
abils := make([]string, 0, 3)
for _, act := range s.Activations {
text, abils = text[:0], abils[:0]
if act.Precondition != "" {
text = append(text, "Precondition: "+formatCondition(act.Precondition))
}
text = append(text, "Condition: "+formatCondition(act.Condition))
var t string
switch {
case act.Duration < 0:
// passive; do nothing
case act.Duration == 0:
t = "Instantaneous "
case act.Duration >= 500e4:
t = "Permanent "
default:
t = "For " + act.Duration.String() + "s, "
}
for _, a := range act.Abilities {
abils = append(abils, a.String())
}
t += strings.Join(abils, ", ")
if act.Cooldown > 0 && act.Cooldown < 500e4 {
t += " on " + act.Cooldown.String() + "s cooldown"
}
text = append(text, t)
r.Components = append(r.Components, discord.NewTextDisplay(strings.Join(text, "\n")))
}
l := discord.NewTextDisplayf("%s ・ SP cost %d ・ Grade value %d ・ [Conditions on GameTora](https://gametora.com/umamusume/skill-condition-viewer?skill=%d)", skilltype, s.SPCost, s.GradeValue, s.ID)
r.Components = append(r.Components, discord.NewSmallSeparator(), l)
rel := make([]horse.Skill, 0, 4)
for _, id := range groups[s.Group] {
if id != 0 {
rel = append(rel, all[id])
}
}
if len(rel) > 1 {
buttons := make([]discord.InteractiveComponent, 0, 4)
for _, rs := range rel {
b := discord.NewSecondaryButton(rs.Name, fmt.Sprintf("/skill/%d", rs.ID))
if rs.ID == id {
b = b.AsDisabled()
}
buttons = append(buttons, b)
}
r.Components = append(r.Components, discord.NewActionRow(buttons...))
}
return r
}
func formatCondition(s string) string {
s = strings.ReplaceAll(s, "&", " & ")
if strings.ContainsRune(s, '@') {
return "```\n" + strings.ReplaceAll(s, "@", "\n@\n") + "```"
}
return "`" + s + "`"
}
func isDebuff(s horse.Skill) bool {
for _, act := range s.Activations {
for _, a := range act.Abilities {
if a.Value < 0 {
return true
}
}
}
return false
}
var skillGlobalAuto = sync.OnceValue(func() *autocomplete.Set[discord.AutocompleteChoice] {
var set autocomplete.Set[discord.AutocompleteChoice]
for _, id := range global.OrderedSkills {
s := global.AllSkills[id]
set.Add(s.Name, discord.AutocompleteChoiceString{Name: s.Name, Value: s.Name})
if s.UniqueOwner != "" {
if s.Rarity >= 3 {
set.Add(s.UniqueOwner, discord.AutocompleteChoiceString{Name: "Unique: " + s.UniqueOwner, Value: s.Name})
} else {
set.Add(s.UniqueOwner, discord.AutocompleteChoiceString{Name: "Inherited unique: " + s.UniqueOwner, Value: s.Name})
}
}
}
return &set
})