Skip to content

Commit

Permalink
Merge branch 'release/3.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
j4rv committed Mar 29, 2024
2 parents 5fdff27 + ce7e657 commit 2c007ec
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 51 deletions.
147 changes: 121 additions & 26 deletions cmd/jarvbot/genshin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

const genshinTeamSize = 4
const genshinChanceIterations = 1000
const gachaPullChanceIterations = 1000
const averagePullsNote = "**Note:** The average rolls spent on each banner include successful attempts and failed attempts. This includes the best case scenarios of not needing to spend all your pulls to get your desired characters/weapons, and the worst case scenarios of spending all your pulls and not getting your desired characters/weapons."

// Command Answers
Expand Down Expand Up @@ -179,7 +179,7 @@ func answerGenshinChance(ds *discordgo.Session, ic *discordgo.InteractionCreate)
cumResult := rollssim.WantedRollsResult{}
successCount := 0

for i := 0; i < genshinChanceIterations; i++ {
for i := 0; i < gachaPullChanceIterations; i++ {
charBanner := rollssim.GenshinCharRoller{
MihoyoRoller: rollssim.MihoyoRoller{
CurrSRPity: charPity,
Expand Down Expand Up @@ -210,43 +210,138 @@ func answerGenshinChance(ds *discordgo.Session, ic *discordgo.InteractionCreate)
}

func formatGenshinChanceResult(result rollssim.WantedRollsResult, successCount int) string {
formatted := fmt.Sprintf("## Chance of success: %.2f%%\n",
divideToFloat(successCount, genshinChanceIterations)*100,
formatted := fmt.Sprintf("## Chance of Success: %.2f%%\n",
divideToFloat(successCount, gachaPullChanceIterations)*100,
)

if result.CharacterBannerRollCount > 0 {
formatted += fmt.Sprintf(`### Character banner:
Average rate up 5\*s characters: %.2f
Average standard 5\*s characters: %.2f
Average rate up 4\*s characters: %.2f
Average standard 4\*s: %.2f
Average rolls spent on character banner: %.2f
Average Rate-Up 5\* Characters: %.2f
Average Standard 5\* Characters: %.2f
Average Rate-Up 4\* Characters: %.2f
Average Standard 4\*s: %.2f
Average Wishes spent on Character banner: %.2f
`,
divideToFloat(result.CharacterBannerRateUpSRCount, genshinChanceIterations),
divideToFloat(result.CharacterBannerStdSRCount, genshinChanceIterations),
divideToFloat(result.CharacterBannerRateUpRareCount, genshinChanceIterations),
divideToFloat(result.CharacterBannerStdRareCount, genshinChanceIterations),
divideToFloat(result.CharacterBannerRollCount, genshinChanceIterations),
divideToFloat(result.CharacterBannerRateUpSRCount, gachaPullChanceIterations),
divideToFloat(result.CharacterBannerStdSRCount, gachaPullChanceIterations),
divideToFloat(result.CharacterBannerRateUpRareCount, gachaPullChanceIterations),
divideToFloat(result.CharacterBannerStdRareCount, gachaPullChanceIterations),
divideToFloat(result.CharacterBannerRollCount, gachaPullChanceIterations),
)
}

if result.WeaponBannerRollCount > 0 {
formatted += fmt.Sprintf(`### Weapon banner:
Average chosen rate up weapons: %.2f
Average non-chosen rate up weapons: %.2f
Average standard 5\* weapons: %.2f
Average rate up 4\*s weapons: %.2f
Average standard 4\*s: %.2f
Average rolls spent on weapon banner: %.2f
Average Chosen Rate-Up 5\* Weapons: %.2f
Average Non-Chosen Rate-Up 5\* Weapons: %.2f
Average Standard 5\* Weapons: %.2f
Average Rate-Up 4\* Weapons: %.2f
Average Standard 4\*s: %.2f
Average Wishes spent on Weapon banner: %.2f
`,
divideToFloat(result.WeaponBannerChosenRateUpCount, genshinChanceIterations),
divideToFloat(result.WeaponBannerNotChosenRateUpCount, genshinChanceIterations),
divideToFloat(result.WeaponBannerStdSRCount, genshinChanceIterations),
divideToFloat(result.WeaponBannerRateUpRareCount, genshinChanceIterations),
divideToFloat(result.WeaponBannerStdRareCount, genshinChanceIterations),
divideToFloat(result.WeaponBannerRollCount, genshinChanceIterations),
divideToFloat(result.WeaponBannerChosenRateUpCount, gachaPullChanceIterations),
divideToFloat(result.WeaponBannerNotChosenRateUpCount, gachaPullChanceIterations),
divideToFloat(result.WeaponBannerStdSRCount, gachaPullChanceIterations),
divideToFloat(result.WeaponBannerRateUpRareCount, gachaPullChanceIterations),
divideToFloat(result.WeaponBannerStdRareCount, gachaPullChanceIterations),
divideToFloat(result.WeaponBannerRollCount, gachaPullChanceIterations),
)
}

formatted += averagePullsNote

return formatted
}

func answerStarRailChance(ds *discordgo.Session, ic *discordgo.InteractionCreate) {
defer func() {
if r := recover(); r != nil {
notifyIfErr("answerStarRailChance panic", fmt.Errorf("%v", r), ds)
}
}()
options := optionMap(ic.ApplicationCommandData().Options)
rollCount := int(options["roll_count"].IntValue())
charCount := int(options["char_count"].IntValue())
weaponCount := int(options["weapon_count"].IntValue())
charPity := optionIntValueOrZero(options["char_pity"])
charGuaranteed := optionBoolValueOrFalse(options["guaranteed_sr_char"])
charRarePity := optionIntValueOrZero(options["char_rare_pity"])
charRareGuaranteed := optionBoolValueOrFalse(options["guaranteed_rare_char"])
weaponPity := optionIntValueOrZero(options["weapon_pity"])
weaponGuaranteed := optionBoolValueOrFalse(options["guaranteed_sr_weapon"])
weaponRarePity := optionIntValueOrZero(options["weapon_rare_pity"])
weaponRareGuaranteed := optionBoolValueOrFalse(options["guaranteed_rare_weapon"])

cumResult := rollssim.WantedRollsResult{}
successCount := 0

for i := 0; i < gachaPullChanceIterations; i++ {
charBanner := rollssim.StarRailCharRoller{
MihoyoRoller: rollssim.MihoyoRoller{
CurrSRPity: charPity,
GuaranteedRateUpSR: charGuaranteed,
CurrRarePity: charRarePity,
GuaranteedRateUpRare: charRareGuaranteed,
},
}
weaponBanner := rollssim.StarRailLCRoller{
MihoyoRoller: rollssim.MihoyoRoller{
CurrSRPity: weaponPity,
GuaranteedRateUpSR: weaponGuaranteed,
CurrRarePity: weaponRarePity,
GuaranteedRateUpRare: weaponRareGuaranteed,
},
}
result := rollssim.CalcStarRailWantedRolls(rollCount, charCount, weaponCount, &charBanner, &weaponBanner)
cumResult.Add(result)

if result.CharacterBannerRateUpSRCount >= charCount && result.WeaponBannerRateUpSRCount >= weaponCount {
successCount++
}
}

_, err := textRespond(ds, ic, formatStarRailChanceResult(cumResult, successCount))
notifyIfErr("answerStarRailChance", err, ds)
}

func formatStarRailChanceResult(result rollssim.WantedRollsResult, successCount int) string {
formatted := fmt.Sprintf("## Chance of Success: %.2f%%\n",
divideToFloat(successCount, gachaPullChanceIterations)*100,
)

if result.CharacterBannerRollCount > 0 {
formatted += fmt.Sprintf(`### Character banner:
Average Rate-Up 5\* Characters: %.2f
Average Standard 5\* Characters: %.2f
Average Rate-Up 4\* Characters: %.2f
Average Standard 4\*s: %.2f
Average Warps spent on Character banner: %.2f
`,
divideToFloat(result.CharacterBannerRateUpSRCount, gachaPullChanceIterations),
divideToFloat(result.CharacterBannerStdSRCount, gachaPullChanceIterations),
divideToFloat(result.CharacterBannerRateUpRareCount, gachaPullChanceIterations),
divideToFloat(result.CharacterBannerStdRareCount, gachaPullChanceIterations),
divideToFloat(result.CharacterBannerRollCount, gachaPullChanceIterations),
)
}

if result.WeaponBannerRollCount > 0 {
formatted += fmt.Sprintf(`### Light Cone banner:
Average Rate-Up 5\* Light Cones: %.2f
Average Standard 5\* Light Cones: %.2f
Average Rate-Up 4\* Light Cones: %.2f
Average Standard 4\*s: %.2f
Average Warps spent on Light Cone banner: %.2f
`,
divideToFloat(result.WeaponBannerRateUpSRCount, gachaPullChanceIterations),
divideToFloat(result.WeaponBannerStdSRCount, gachaPullChanceIterations),
divideToFloat(result.WeaponBannerRateUpRareCount, gachaPullChanceIterations),
divideToFloat(result.WeaponBannerStdRareCount, gachaPullChanceIterations),
divideToFloat(result.WeaponBannerRollCount, gachaPullChanceIterations),
)
}

Expand Down
107 changes: 97 additions & 10 deletions cmd/jarvbot/slash_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var slashCommands = []*discordgo.ApplicationCommand{
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "roll_count",
Description: "The amount of rolls you have.",
Description: "The amount of wishes you have.",
Required: true,
MinValue: &zero,
MaxValue: 1500,
Expand Down Expand Up @@ -125,6 +125,92 @@ var slashCommands = []*discordgo.ApplicationCommand{
},
},
},
{
Name: "star_rail_chances",
Description: "Your chance to get a Honkai: Star Rail character with specific constellations and refinements",
Options: []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "roll_count",
Description: "The amount of warps you have.",
Required: true,
MinValue: &zero,
MaxValue: 1400,
},
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "char_count",
Description: "The amount of characters you want to pull. 0 for none, 1 for E0, 7 for E6.",
Required: true,
MinValue: &zero,
MaxValue: 7,
},
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "weapon_count",
Description: "The amount of light cones you want to pull. 0 for none, 1 for S1, 5 for S5.",
Required: true,
MinValue: &zero,
MaxValue: 5,
},
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "char_pity",
Description: "Your limited character banner 5* pity count.",
Required: false,
MinValue: &zero,
MaxValue: 89,
},
{
Type: discordgo.ApplicationCommandOptionBoolean,
Name: "guaranteed_sr_char",
Description: "If the next 5* character is guaranteed to be the rate up.",
Required: false,
},
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "char_rare_pity",
Description: "Your limited character banner 4* pity count.",
Required: false,
MinValue: &zero,
MaxValue: 9,
},
{
Type: discordgo.ApplicationCommandOptionBoolean,
Name: "guaranteed_rare_char",
Description: "If the next 4* character is guaranteed to be a rate up.",
Required: false,
},
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "weapon_pity",
Description: "Your limited light cone banner 5* pity count.",
Required: false,
MinValue: &zero,
MaxValue: 89,
},
{
Type: discordgo.ApplicationCommandOptionBoolean,
Name: "guaranteed_sr_weapon",
Description: "If the next 5* light cone is guaranteed to be the rate up.",
Required: false,
},
{
Type: discordgo.ApplicationCommandOptionInteger,
Name: "weapon_rare_pity",
Description: "Your limited light cone banner 4* pity count.",
Required: false,
MinValue: &zero,
MaxValue: 9,
},
{
Type: discordgo.ApplicationCommandOptionBoolean,
Name: "guaranteed_rare_weapon",
Description: "If the next 4* light cone is guaranteed to be a rate up.",
Required: false,
},
},
},
{
Name: "strongbox",
Description: "Do Strongbox rolls of your set of choice",
Expand Down Expand Up @@ -205,15 +291,16 @@ var slashCommands = []*discordgo.ApplicationCommand{
}

var slashHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){
"help": answerHelp,
"8ball": answer8ball,
"avatar": answerAvatar,
"genshin_chances": expensiveSlashCommand(answerGenshinChance),
"strongbox": expensiveSlashCommand(answerStrongbox),
"character": answerCharacter,
"abyss_challenge": answerAbyssChallenge,
"warn": answerWarn,
"warnings": answerWarnings,
"help": answerHelp,
"8ball": answer8ball,
"avatar": answerAvatar,
"genshin_chances": expensiveSlashCommand(answerGenshinChance),
"star_rail_chances": expensiveSlashCommand(answerStarRailChance),
"strongbox": expensiveSlashCommand(answerStrongbox),
"character": answerCharacter,
"abyss_challenge": answerAbyssChallenge,
"warn": answerWarn,
"warnings": answerWarnings,
}

func expensiveSlashCommand(expensiveOp func(ds *discordgo.Session, ic *discordgo.InteractionCreate)) func(ds *discordgo.Session, ic *discordgo.InteractionCreate) {
Expand Down
3 changes: 3 additions & 0 deletions cmd/jarvbot/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ func removeRoleAfterDuration(ds *discordgo.Session, guildID string, memberID str
var usersOnExpensiveOperationCooldown = make(map[string]struct{})

func userExpensiveOperationOnCooldown(userID string) bool {
if userID == adminID {
return false
}
_, inCooldown := usersOnExpensiveOperationCooldown[userID]
return inCooldown
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ require (
github.com/bwmarrin/discordgo v0.27.1
github.com/enescakir/emoji v1.0.0
github.com/j4rv/genshinartis v0.0.0-20230911183910-b19c3dc323f3
github.com/j4rv/rollssim v0.0.0-20240329011720-1ac34fe7b422
github.com/jmoiron/sqlx v1.3.5
github.com/mattn/go-sqlite3 v1.14.22
github.com/robfig/cron/v3 v3.0.1
)

require (
github.com/gorilla/websocket v1.5.1 // indirect
github.com/j4rv/rollssim v0.0.0-20240328173749-ed06730e3472 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sys v0.18.0 // indirect
Expand Down
16 changes: 2 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/j4rv/genshinartis v0.0.0-20230911183910-b19c3dc323f3 h1:bdBq6XxKRQvZWRyunxC/Svo5cTEfJ49S75qBvOUSH9w=
github.com/j4rv/genshinartis v0.0.0-20230911183910-b19c3dc323f3/go.mod h1:NXUI4xa2rw8D2BjTBqgT6934wIJXJgn1vG9x/FGXW4E=
github.com/j4rv/rollssim v0.0.0-20240328145921-b2c451d22b1d h1:lAPUtWKh8GSUIlD0W0pvihcuTey9+oThRyYiamTALjU=
github.com/j4rv/rollssim v0.0.0-20240328145921-b2c451d22b1d/go.mod h1:giZ+GfPdq1sGjpWZHM5YSQ7Pfz2/doB9I2uSUXl/ZxU=
github.com/j4rv/rollssim v0.0.0-20240328153522-13b27c74ce9e h1:+0hVvtd5zchRJM0io+PHwbm3cQtTb1kkQPYOKYJZZF0=
github.com/j4rv/rollssim v0.0.0-20240328153522-13b27c74ce9e/go.mod h1:giZ+GfPdq1sGjpWZHM5YSQ7Pfz2/doB9I2uSUXl/ZxU=
github.com/j4rv/rollssim v0.0.0-20240328172521-0660e174d545 h1:HYsFGFpYIRotH/vrUfKdORN0RPSctSCHM2aCuOQRcmg=
github.com/j4rv/rollssim v0.0.0-20240328172521-0660e174d545/go.mod h1:giZ+GfPdq1sGjpWZHM5YSQ7Pfz2/doB9I2uSUXl/ZxU=
github.com/j4rv/rollssim v0.0.0-20240328173749-ed06730e3472 h1:z6LRJfZUXlw5R9koVUlsAb9GoFp2NLC1ihyjfPNacso=
github.com/j4rv/rollssim v0.0.0-20240328173749-ed06730e3472/go.mod h1:giZ+GfPdq1sGjpWZHM5YSQ7Pfz2/doB9I2uSUXl/ZxU=
github.com/j4rv/rollssim v0.0.0-20240329011720-1ac34fe7b422 h1:hB8eYD6EUsqv8KagIC/vVrm1/k9exSi/o+Za2fcvTrM=
github.com/j4rv/rollssim v0.0.0-20240329011720-1ac34fe7b422/go.mod h1:giZ+GfPdq1sGjpWZHM5YSQ7Pfz2/doB9I2uSUXl/ZxU=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
Expand All @@ -27,18 +21,12 @@ github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
Expand Down

0 comments on commit 2c007ec

Please sign in to comment.