xp: Implement level querying

master 0.1
Luther Wen Xu 2019-11-18 12:25:34 +07:00
parent 705eb52759
commit f1112c2fbf
Signed by: chanbakjsd
GPG Key ID: B7D77E3E9D102B70
2 changed files with 51 additions and 2 deletions

@ -1,6 +1,10 @@
package main package main
import "github.com/bwmarrin/discordgo" import (
"fmt"
"github.com/bwmarrin/discordgo"
)
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.Author.Bot { if m.Author.Bot {
@ -8,5 +12,15 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
} }
go incrementXP(s, m.Author.ID) go incrementXP(s, m.Author.ID)
//TODO Handle commands if m.Content == "p!level" {
handleXPRequest(s, m)
}
}
func handleXPRequest(s *discordgo.Session, m *discordgo.MessageCreate) {
level, xp := getLevelAndXP(s, m.Author.ID)
s.ChannelMessageSend(
m.ChannelID,
fmt.Sprintf("<@%s> is now level %d. (%d XP/%d XP)", m.Author.ID, level, xp, levelUpRequirementCache[level-1]),
)
} }

35
xp.go

@ -13,6 +13,7 @@ import (
var db *sql.DB var db *sql.DB
var lastMessage = make(map[string]time.Time) var lastMessage = make(map[string]time.Time)
var incrementMutex = sync.Mutex{} var incrementMutex = sync.Mutex{}
var levelUpRequirementCache [30]int
func init() { func init() {
var err error var err error
@ -22,6 +23,13 @@ func init() {
} }
db.SetMaxOpenConns(1) db.SetMaxOpenConns(1)
db.Exec("CREATE TABLE xp(id STRING NOT NULL UNIQUE, xp INTEGER NOT NULL)") db.Exec("CREATE TABLE xp(id STRING NOT NULL UNIQUE, xp INTEGER NOT NULL)")
for i := 1; i <= 30; i++ {
//Constructed on Desmos:
//y=2^{\frac{x}{3}}+.1x^{2}+1.2x-1
fi := float64(i)
levelUpRequirementCache[i-1] = int(10000 * (math.Pow(2, fi/3) + 0.1*fi*fi + 1.2*fi - 1))
}
} }
func incrementXP(dg *discordgo.Session, discordID string) { func incrementXP(dg *discordgo.Session, discordID string) {
@ -45,6 +53,21 @@ func incrementXP(dg *discordgo.Session, discordID string) {
} }
} }
func getLevelAndXP(dg *discordgo.Session, discordID string) (int, int) {
rows, err := db.Query("SELECT xp FROM xp WHERE id=?", discordID)
if err != nil {
logError(dg, "getLevelAndXP", "select", discordID, err)
return 1, 0
}
defer rows.Close()
if rows.Next() {
var xp int
rows.Scan(&xp)
return convertXPIntoLevel(xp)
}
return 1, 0
}
func calculateIncrement(discordID string) int { func calculateIncrement(discordID string) int {
incrementMutex.Lock() incrementMutex.Lock()
defer incrementMutex.Unlock() defer incrementMutex.Unlock()
@ -61,3 +84,15 @@ func calculateIncrement(discordID string) int {
//y=\frac{100}{\left(1+e^{-\left(\frac{x-15}{3}\right)}\right)} //y=\frac{100}{\left(1+e^{-\left(\frac{x-15}{3}\right)}\right)}
return int(100 / (1 + math.Pow(math.E, -((delta.Seconds()-15)/3)))) return int(100 / (1 + math.Pow(math.E, -((delta.Seconds()-15)/3))))
} }
func convertXPIntoLevel(xp int) (int, int) {
if xp < levelUpRequirementCache[0] {
return 1, xp
}
for i := 0; i < 30; i++ {
if levelUpRequirementCache[i] > xp {
return i + 1, xp - levelUpRequirementCache[i-1]
}
}
return 30, xp - levelUpRequirementCache[29]
}