bb/bot/handler/dice.go

131 lines
2.0 KiB
Go
Raw Normal View History

2022-08-24 14:06:00 +00:00
package handler
2022-07-26 14:28:02 +00:00
import (
"errors"
"fmt"
"regexp"
"strconv"
"strings"
2022-08-23 16:52:36 +00:00
"git.kill0.net/chill9/beepboop/bot"
2022-08-24 14:06:00 +00:00
"git.kill0.net/chill9/beepboop/lib"
2022-07-26 14:28:02 +00:00
"github.com/bwmarrin/discordgo"
log "github.com/sirupsen/logrus"
)
const (
2022-08-25 15:00:43 +00:00
MaxDice = 100
MaxSides = 100
2022-07-26 14:28:02 +00:00
)
type (
Roll struct {
N, D, Sum int
Rolls []int
S string
}
RollHandler struct {
2022-08-23 16:52:36 +00:00
config bot.Config
}
2022-07-26 14:28:02 +00:00
)
func NewRoll(n, d int) *Roll {
r := new(Roll)
r.N = n
r.D = d
r.S = fmt.Sprintf("%dd%d", r.N, r.D)
return r
}
func ParseRoll(roll string) (*Roll, error) {
var (
dice []string
err error
n, d int
)
match, _ := regexp.MatchString(`^(?:\d+)?d\d+$`, roll)
if !match {
return nil, errors.New("invalid roll, use `<n>d<sides>` e.g. `4d6`")
}
dice = strings.Split(roll, "d")
if dice[0] == "" {
n = 1
} else {
n, err = strconv.Atoi(dice[0])
if err != nil {
return nil, err
}
}
d, err = strconv.Atoi(dice[1])
if err != nil {
return nil, err
}
if n > MaxDice || d > MaxSides {
return nil, fmt.Errorf("invalid roll, n must be <= %d and sides must be <= %d", MaxDice, MaxSides)
}
return NewRoll(n, d), nil
}
func (r *Roll) RollDice() {
for i := 1; i <= r.N; i++ {
2022-08-24 14:06:00 +00:00
roll := lib.RandInt(1, r.D)
2022-07-26 14:28:02 +00:00
r.Rolls = append(r.Rolls, roll)
r.Sum += roll
}
}
2022-07-28 04:43:08 +00:00
func NewRollHandler() *RollHandler {
return new(RollHandler)
}
2022-08-23 16:52:36 +00:00
func (h *RollHandler) SetConfig(config bot.Config) {
h.config = config
}
2022-07-28 04:43:08 +00:00
func (h *RollHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) {
2022-07-26 14:28:02 +00:00
var (
err error
msg, roll string
r *Roll
)
if m.Author.ID == s.State.User.ID {
return
}
if !strings.HasPrefix(m.Content, "!roll") {
return
}
x := strings.Split(m.Content, " ")
if len(x) != 2 {
s.ChannelMessageSend(m.ChannelID, "help: `!roll <n>d<s>`")
return
}
roll = x[1]
r, err = ParseRoll(roll)
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
return
}
r.RollDice()
log.Debugf("rolled dice: %+v", r)
2022-08-24 14:06:00 +00:00
msg = fmt.Sprintf("🎲 %s = %d", lib.JoinInt(r.Rolls, " + "), r.Sum)
2022-07-26 14:28:02 +00:00
s.ChannelMessageSend(m.ChannelID, msg)
}