121 lines
3.5 KiB
Go
121 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"git.sunturtle.xyz/zephyr/horse/horse"
|
|
"github.com/disgoorg/disgo/discord"
|
|
)
|
|
|
|
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)
|
|
r := discord.NewContainer(discord.NewSection(discord.NewTextDisplayf("## %s\n%s", s.Name, 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.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
|
|
}
|
|
|
|
// TODO(zeph): autocomplete
|
|
// if we want to backgroundify construction of an autocomplete map,
|
|
// use sync.OnceValue and launch a goroutine in main to get the value and discard it
|