all repos — disgord @ 41b487beb8025d82e480ed8899f028ac2d381a06

A simple Discord bot in Go.

src/shoot.go (view raw)

  1package src
  2
  3import (
  4	"fmt"
  5	"time"
  6
  7	"github.com/bwmarrin/discordgo"
  8	"golang.org/x/exp/rand"
  9)
 10
 11type Magazine struct {
 12	size uint
 13	left uint
 14	last time.Time
 15}
 16
 17var magazines = map[string]*Magazine{}
 18
 19func NewMagazine(size uint) *Magazine {
 20	return &Magazine{size: size, left: size, last: time.Now()}
 21}
 22
 23func (m *Magazine) Update() {
 24	now := time.Now()
 25	if m.last.YearDay() != now.YearDay() || m.last.Year() != now.Year() {
 26		m.left = m.size
 27	}
 28}
 29
 30func (m *Magazine) Left() uint {
 31	m.Update()
 32	return m.left
 33}
 34
 35func (m Magazine) Size() uint {
 36	return m.size
 37}
 38
 39func (m *Magazine) Shoot() bool {
 40	if m.Left() <= 0 {
 41		return false
 42	}
 43
 44	m.last = time.Now()
 45	m.left--
 46	return true
 47}
 48
 49func (m *Magazine) String() string {
 50	return fmt.Sprintf("_%d/%d bullets left in your magazine._", m.Left(), m.Size())
 51}
 52
 53func GetMagazine(userID string) (q *Magazine) {
 54	q, ok := magazines[userID]
 55	if ok {
 56		return
 57	}
 58
 59	q = NewMagazine(Config.Values.MagazineSize)
 60	magazines[userID] = q
 61	return
 62}
 63
 64func handleShoot(args []string, s *discordgo.Session, m *discordgo.MessageCreate) string {
 65	const bustProbability = 50
 66
 67	response, guild, voiceChannelID := getVoiceChannelID(s, m)
 68	if voiceChannelID == "" {
 69		return response
 70	}
 71
 72	killerID := m.Author.ID
 73	var allMembers []string
 74	for _, vs := range guild.VoiceStates {
 75		logger.Debug(vs.UserID)
 76		if vs.ChannelID == voiceChannelID && vs.UserID != killerID {
 77			member, err := s.State.Member(guild.ID, vs.UserID)
 78			if err != nil {
 79				logger.Errorf("could not get member info: %s", err)
 80				continue
 81			}
 82			if !member.User.Bot {
 83				allMembers = append(allMembers, vs.UserID)
 84			}
 85		}
 86	}
 87
 88	if len(allMembers) == 0 {
 89		return "There is no one else to shoot in your voice channel."
 90	}
 91
 92	magazine := GetMagazine(killerID)
 93	if !magazine.Shoot() {
 94		return "💨 Too bad... You're out of bullets."
 95	}
 96
 97	var victimID string
 98	if rand.Intn(100) < bustProbability {
 99		victimID = killerID
100	} else {
101		victimID = allMembers[rand.Intn(len(allMembers))]
102	}
103
104	err := s.GuildMemberMove(m.GuildID, victimID, nil)
105	if err != nil {
106		logger.Errorf("could not kick user: %s", err)
107		return "Failed to kick the user from the voice channel."
108	}
109
110	return "💥 *Bang!* <@" + victimID + "> was shot. " + magazine.String()
111}