diff --git a/go.mod b/go.mod index 86d727d..bf9cf8d 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.sunturtle.xyz/zephyr/horsebot go 1.24.1 require ( - git.sunturtle.xyz/zephyr/horse v0.0.0-20260116044610-b0c555f547e4 + git.sunturtle.xyz/zephyr/horse v0.0.0-20260117030110-cb1c51db05bb github.com/disgoorg/disgo v0.19.0-rc.15 ) diff --git a/go.sum b/go.sum index a1d53fe..1af5fb5 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,9 @@ git.sunturtle.xyz/zephyr/horse v0.0.0-20260116044610-b0c555f547e4 h1:YJEGZG/EnxE5Tr6EZMGxikXDF6QKKHrH9Bp1dLoWXkk= git.sunturtle.xyz/zephyr/horse v0.0.0-20260116044610-b0c555f547e4/go.mod h1:qGXO/93EfCOI1oGSLqrRkPDF/EAdsgLNZJjRKx+i4Lk= +git.sunturtle.xyz/zephyr/horse v0.0.0-20260117022630-19fb713aaa10 h1:soAAeJR/omxESc0ne1ItNxTpTv7ahyr4HbjU3PjEIvM= +git.sunturtle.xyz/zephyr/horse v0.0.0-20260117022630-19fb713aaa10/go.mod h1:qGXO/93EfCOI1oGSLqrRkPDF/EAdsgLNZJjRKx+i4Lk= +git.sunturtle.xyz/zephyr/horse v0.0.0-20260117030110-cb1c51db05bb h1:iFPbu8i9sRakUnvRX9UzBd/RsVQkf6Nn3sOG/8F6QKM= +git.sunturtle.xyz/zephyr/horse v0.0.0-20260117030110-cb1c51db05bb/go.mod h1:qGXO/93EfCOI1oGSLqrRkPDF/EAdsgLNZJjRKx+i4Lk= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/disgoorg/disgo v0.19.0-rc.15 h1:x0NsV2gcbdjwuztsg2wYXw76p1Cpc8f6ByDrkPcfQtU= diff --git a/main.go b/main.go index 117f7f7..9c8fde2 100644 --- a/main.go +++ b/main.go @@ -48,7 +48,7 @@ func main() { r.Route("/skill", func(r handler.Router) { r.SlashCommand("/", skillHandler) r.Autocomplete("/", skillAutocomplete) - // TODO(zeph): button handler + r.ButtonComponent("/{id}", skillButton) }) slog.Info("connect", slog.String("disgo", disgo.Version)) @@ -94,15 +94,14 @@ var commands = []discord.ApplicationCommandCreate{ func skillHandler(data discord.SlashCommandInteractionData, e *handler.CommandEvent) error { q := data.String("query") id, err := strconv.ParseInt(q, 10, 32) - var s horse.Skill if err == nil { // note inverted condition; this is when we have an id - s = global.AllSkills[horse.SkillID(id)] + id = int64(global.AllSkills[horse.SkillID(id)].ID) } - if s.ID == 0 { + if id == 0 { // Either we weren't given a number or the number doesn't match any skill ID. - id, ok := global.SkillNameToID[q] - if !ok { + v := global.SkillNameToID[q] + if v == 0 { // No such skill. m := discord.MessageCreate{ Content: "No such skill.", @@ -110,11 +109,11 @@ func skillHandler(data discord.SlashCommandInteractionData, e *handler.CommandEv } return e.CreateMessage(m) } - s = global.AllSkills[id] + id = int64(v) } // TODO(zeph): search conditions and effects, give a list m := discord.MessageCreate{ - Components: []discord.LayoutComponent{RenderSkill(s)}, + Components: []discord.LayoutComponent{RenderSkill(horse.SkillID(id), global.AllSkills, global.SkillGroups)}, Flags: discord.MessageFlagIsComponentsV2, } return e.CreateMessage(m) @@ -133,3 +132,18 @@ func skillAutocomplete(e *handler.AutocompleteEvent) error { } return e.AutocompleteResult(r) } + +func skillButton(data discord.ButtonInteractionData, e *handler.ComponentEvent) error { + id, err := strconv.ParseInt(e.Vars["id"], 10, 32) + if err != nil { + m := discord.MessageCreate{ + Content: "That button produced an invalid skill ID. That's not supposed to happen.", + Flags: discord.MessageFlagEphemeral, + } + return e.CreateMessage(m) + } + m := discord.MessageUpdate{ + Components: &[]discord.LayoutComponent{RenderSkill(horse.SkillID(id), global.AllSkills, global.SkillGroups)}, + } + return e.UpdateMessage(m) +} diff --git a/skill.go b/skill.go index 251ea10..4b051b6 100644 --- a/skill.go +++ b/skill.go @@ -8,7 +8,11 @@ import ( "github.com/disgoorg/disgo/discord" ) -func RenderSkill(s horse.Skill) discord.ContainerComponent { +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)) + } skilltype := discord.TextDisplayComponent{ ID: 4, Content: "Skill Issue", @@ -90,7 +94,19 @@ func RenderSkill(s horse.Skill) discord.ContainerComponent { ID: 51, Content: fmt.Sprintf("SP cost %d. Grade value %d.", s.SPCost, s.GradeValue), }) - // TODO(zeph): related skills, use a row of buttons with skill numbers for the ids and edit the message when clicked? + 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 { + buttons = append(buttons, discord.NewButton(discord.ButtonStyleSecondary, rs.Name, fmt.Sprintf("/skill/%d", rs.ID), "", 0)) + } + r.Components = append(r.Components, discord.NewActionRow(buttons...)) + } return r }