diff --git a/cmd/horsebot/main.go b/cmd/horsebot/main.go index b3df620..a8c617a 100644 --- a/cmd/horsebot/main.go +++ b/cmd/horsebot/main.go @@ -84,6 +84,7 @@ func main() { r.Route("/skill", func(r handler.Router) { r.SlashCommand("/", skillSrv.slash) r.Autocomplete("/", skillSrv.autocomplete) + r.SelectMenuComponent("/swap", skillSrv.menu) r.ButtonComponent("/swap/{id}", skillSrv.button) }) diff --git a/cmd/horsebot/skill.go b/cmd/horsebot/skill.go index 959183f..b79ad27 100644 --- a/cmd/horsebot/skill.go +++ b/cmd/horsebot/skill.go @@ -97,6 +97,24 @@ func (s *skillServer) button(data discord.ButtonInteractionData, e *handler.Comp return e.UpdateMessage(m) } +func (s *skillServer) menu(data discord.SelectMenuInteractionData, e *handler.ComponentEvent) error { + d, ok := data.(discord.StringSelectMenuInteractionData) + if !ok { + return fmt.Errorf("wrong select menu type %T", data) + } + if len(d.Values) != 1 { + return fmt.Errorf("wrong number of values: %q", d.Values) + } + id, err := strconv.ParseInt(d.Values[0], 10, 32) + if err != nil { + return err + } + m := discord.MessageUpdate{ + Components: &[]discord.LayoutComponent{s.render(horse.SkillID(id))}, + } + return e.UpdateMessage(m) +} + func (s *skillServer) render(id horse.SkillID) discord.ContainerComponent { skill, ok := s.skills[id] if !ok { @@ -104,16 +122,13 @@ func (s *skillServer) render(id horse.SkillID) discord.ContainerComponent { return discord.NewContainer(discord.NewTextDisplayf("invalid skill ID %v made it to render", id)) } - thumburl := fmt.Sprintf("https://gametora.com/images/umamusume/skill_icons/utx_ico_skill_%d.png", skill.IconID) - top := "## " + skill.Name + top := "### " + skill.Name if skill.UniqueOwner != "" { top += "\n-# " + skill.UniqueOwner } r := discord.NewContainer( - discord.NewSection( - discord.NewTextDisplay(top), - discord.NewTextDisplay(skill.Description), - ).WithAccessory(discord.NewThumbnail(thumburl)), + discord.NewTextDisplay(top), + discord.NewSmallSeparator(), ) var skilltype string switch { @@ -145,7 +160,6 @@ func (s *skillServer) render(id horse.SkillID) discord.ContainerComponent { 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 skill.Activations { @@ -188,19 +202,30 @@ func (s *skillServer) render(id horse.SkillID) discord.ContainerComponent { } } if len(rel) > 1 { - buttons := make([]discord.InteractiveComponent, 0, 4) + opts := make([]discord.StringSelectMenuOption, 0, 4) for _, rs := range rel { name := rs.Name - if u := s.skills[rs.ID]; u.UniqueOwner != "" && u.Rarity == 1 { - name += " (Inherited)" + emoji := "⚪" + switch rs.Rarity { + case 1: + if rs.UniqueOwner != "" { + name += " (Inherited)" + } + case 2: + emoji = "🟡" + case 3, 4, 5: + emoji = "🟣" + default: + emoji = "⁉️" } - b := discord.NewSecondaryButton(name, fmt.Sprintf("/skill/swap/%d", rs.ID)) - if rs.ID == id { - b = b.AsDisabled() + b := discord.NewStringSelectMenuOption(name, strconv.Itoa(int(rs.ID))).WithEmoji(discord.NewComponentEmoji(emoji)) + if rs.ID == skill.ID { + b = b.WithDefault(true) } - buttons = append(buttons, b) + opts = append(opts, b) } - r.Components = append(r.Components, discord.NewActionRow(buttons...)) + row := discord.NewActionRow(discord.NewStringSelectMenu("/skill/swap", "Related skills", opts...)) + r.Components = append(r.Components, row) } return r } diff --git a/doc/README.md b/doc/README.md index fa50e93..be0384d 100644 --- a/doc/README.md +++ b/doc/README.md @@ -192,8 +192,6 @@ target types: - 22 specific character, target value is character id - 23 other who triggered the skill -TODO target types only in jp: 2, 7, 11, 22, 23 - ability_value_usage can be 1 for plain or 2-6 for aoharu stat skill stat scaling seems to be activate_lot = 1 means wit check, 0 means guaranteed