88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/bwmarrin/discordgo"
|
|
|
|
"PermissionGacha/db"
|
|
)
|
|
|
|
const notInGeneralNerf = 10
|
|
|
|
const generalChannelID = "645550570001924098"
|
|
|
|
var lastMessage = make(map[string]time.Time)
|
|
var incrementMutex = sync.Mutex{}
|
|
var levelUpRequirementCache [30]int
|
|
|
|
func init() {
|
|
for i := 1; i <= 30; i++ {
|
|
//Constructed on Desmos:
|
|
//y=2^{\frac{x}{2}}+.1x^{2}+1.2x-1
|
|
fi := float64(i)
|
|
levelUpRequirementCache[i-1] = int(10000 * (math.Pow(2, fi/2) + 0.1*fi*fi + 1.2*fi - 1))
|
|
}
|
|
}
|
|
|
|
func incrementXP(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|
amountToIncrement := calculateIncrement(m.Author.ID)
|
|
if m.ChannelID != generalChannelID {
|
|
amountToIncrement /= notInGeneralNerf
|
|
}
|
|
multiplier, err := db.GetPrestigeMultiplier(m.Author.ID)
|
|
if err != nil {
|
|
logError(s, err)
|
|
return
|
|
}
|
|
amountToIncrement *= multiplier
|
|
|
|
err = db.IncrementXP(m.Author.ID, amountToIncrement)
|
|
if err != nil {
|
|
logError(s, err)
|
|
return
|
|
}
|
|
addToLevelQueue(m.Author.ID)
|
|
}
|
|
|
|
func calculateIncrement(discordID string) int {
|
|
incrementMutex.Lock()
|
|
defer incrementMutex.Unlock()
|
|
|
|
now := time.Now()
|
|
delta := now.Sub(lastMessage[discordID])
|
|
lastMessage[discordID] = now
|
|
|
|
if delta.Seconds() < 0 {
|
|
return 0
|
|
}
|
|
|
|
//Constructed on Desmos:
|
|
//y=\frac{100}{\left(1+e^{-\left(\frac{x}{2}-5\right)}\right)}
|
|
return int(100 / (1 + math.Pow(math.E, -((delta.Seconds()/2)-5))))
|
|
}
|
|
|
|
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]
|
|
}
|
|
|
|
func getLevelAndXP(discordID string) (int, int, error) {
|
|
rawXP, err := db.GetXP(discordID)
|
|
if err != nil {
|
|
return 1, 0, fmt.Errorf("xp: getLevelAndXP: error requesting XP: %w", err)
|
|
}
|
|
level, xp := convertXPIntoLevel(rawXP)
|
|
return level, xp, nil
|
|
}
|