all repos — disgord @ 1b8f5834bbf4f6a1fb79a5f46a77c1d41007c600

A simple Discord bot in Go.

shoot.go (view raw)

  1package main
  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		if vs.ChannelID == voiceChannelID && vs.UserID != killerID {
 76			member, err := s.State.Member(guild.ID, vs.UserID)
 77			if err != nil {
 78				logger.Errorf("could not get member info: %s", err)
 79				continue
 80			}
 81			if !member.User.Bot {
 82				allMembers = append(allMembers, vs.UserID)
 83			}
 84		}
 85	}
 86
 87	if len(allMembers) == 0 {
 88		return "There is no one else to shoot in your voice channel."
 89	}
 90
 91	magazine := GetMagazine(killerID)
 92	if !magazine.Shoot() {
 93		return "💨 Too bad... You're out of bullets."
 94	}
 95
 96	var victimID string
 97	if rand.Intn(100) < bustProbability {
 98		victimID = killerID
 99	} else {
100		victimID = allMembers[rand.Intn(len(allMembers))]
101	}
102
103	err := s.GuildMemberMove(m.GuildID, victimID, nil)
104	if err != nil {
105		logger.Errorf("could not kick user: %s", err)
106		return "Failed to kick the user from the voice channel."
107	}
108
109	return "💥 *Bang!* <@" + victimID + "> was shot. " + magazine.String()
110}