Replaced .wheel with .lula (lucky ladder). It looks nicer but plays the same. Also it is more customizable as you can have more or less multipliers. Cleaned up some trivia code. Sorted lula multipliers in gambling.yml. Improved .slottest

This commit is contained in:
Kwoth
2022-07-14 03:52:30 +02:00
parent 17ca609fe9
commit d9011106ac
15 changed files with 262 additions and 195 deletions

View File

@@ -834,7 +834,7 @@ public partial class Gambling : GamblingModule<GamblingService>
new[] { "⬆", "↖", "⬅", "↙", "⬇", "↘", "➡", "↗" }.ToImmutableArray();
[Cmd]
public async partial Task WheelOfFortune(ShmartNumber amount)
public async partial Task LuckyLadder(ShmartNumber amount)
{
if (!await CheckBetMandatory(amount))
return;
@@ -846,13 +846,29 @@ public partial class Gambling : GamblingModule<GamblingService>
return;
}
var wofMultipliers = Config.WheelOfFortune.Multipliers;
await SendConfirmAsync(Format.Bold($@"{ctx.User} won: {N(result.Won)}
var multis = result.Multipliers;
『{wofMultipliers[1]}』 『{wofMultipliers[0]}』 『{wofMultipliers[7]}』
var sb = new StringBuilder();
foreach (var multi in multis)
{
sb.Append($"╠══╣");
『{wofMultipliers[2]}』 {_emojis[result.Index]} 『{wofMultipliers[6]}』
if (multi == result.Multiplier)
sb.Append($"{Format.Bold($"x{multi:0.##}")} ⬅️");
else
sb.Append($"||x{multi:0.##}||");
sb.AppendLine();
}
『{wofMultipliers[3]}』 『{wofMultipliers[4]}』 『{wofMultipliers[5]}』"));
var eb = _eb.Create(ctx)
.WithOkColor()
.WithDescription(sb.ToString())
.AddField(GetText(strs.multiplier), $"{result.Multiplier:0.##}x", true)
.AddField(GetText(strs.won), $"{(long)result.Won}", true)
.WithAuthor(ctx.User);
await ctx.Channel.EmbedAsync(eb);
}
}

View File

@@ -39,8 +39,8 @@ Set 0 for unlimited")]
[Comment(@"How much will each user's owned currency decay over time.")]
public DecayConfig Decay { get; set; }
[Comment(@"Settings for Wheel Of Fortune command.")]
public WheelOfFortuneSettings WheelOfFortune { get; set; }
[Comment(@"Settings for LuckyLadder command")]
public LuckyLadderSettings LuckyLadder { get; set; }
[Comment(@"Settings related to waifus")]
public WaifuConfig Waifu { get; set; }
@@ -59,7 +59,6 @@ This will work only if you've set up VotesApi and correct credentials for topgg
public GamblingConfig()
{
BetRoll = new();
WheelOfFortune = new();
Waifu = new();
Currency = new();
BetFlip = new();
@@ -67,6 +66,7 @@ This will work only if you've set up VotesApi and correct credentials for topgg
Timely = new();
Decay = new();
Slots = new();
LuckyLadder = new();
}
}
@@ -173,13 +173,13 @@ public partial class DecayConfig
}
[Cloneable]
public partial class WheelOfFortuneSettings
public partial class LuckyLadderSettings
{
[Comment(@"Self-Explanatory. Has to have 8 values, otherwise the command won't work.")]
public decimal[] Multipliers { get; set; }
public WheelOfFortuneSettings()
=> Multipliers = new[] { 1.7M, 1.5M, 0.2M, 0.1M, 0.3M, 0.5M, 1.2M, 2.4M };
public LuckyLadderSettings()
=> Multipliers = new[] { 2.4M, 1.7M, 1.5M, 1.2M, 0.5M, 0.3M, 0.2M, 0.1M };
}
[Cloneable]

View File

@@ -174,5 +174,13 @@ public sealed class GamblingConfigService : ConfigServiceBase<GamblingConfig>
c.Version = 5;
});
}
if (data.Version < 6)
{
ModifyConfig(c =>
{
c.Version = 6;
});
}
}
}

View File

@@ -81,6 +81,11 @@ public partial class Gambling
if (tests <= 0)
return;
//multi vs how many times it occured
int streak = 0;
int maxW = 0;
int maxL = 0;
var dict = new Dictionary<decimal, int>();
for (var i = 0; i < tests; i++)
{
@@ -90,16 +95,39 @@ public partial class Gambling
dict[multi] += 1;
else
dict.Add(multi, 1);
}
if (multi == 0)
{
if (streak <= 0)
--streak;
else
streak = -1;
maxL = Math.Max(maxL, -streak);
}
else
{
if (streak >= 0)
++streak;
else
streak = 1;
maxW = Math.Max(maxW, streak);
}
}
var sb = new StringBuilder();
decimal payout = 0;
foreach (var key in dict.Keys.OrderByDescending(x => x))
{
sb.AppendLine($"x{key} occured {dict[key]} times. {dict[key] * 1.0f / tests * 100}%");
sb.AppendLine($"x{key} occured `{dict[key]}` times. {dict[key] * 1.0f / tests * 100}%");
payout += key * dict[key];
}
sb.AppendLine();
sb.AppendLine($"Longest win streak: `{maxW}`");
sb.AppendLine($"Longest lose streak: `{maxL}`");
await SendConfirmAsync("Slot Test Results",
sb.ToString(),
footer: $"Total Bet: {tests} | Payout: {payout:F0} | {payout * 1.0M / tests * 100}%");

View File

@@ -7,7 +7,7 @@ namespace NadekoBot.Modules.Gambling;
public interface IGamblingService
{
Task<OneOf<WofResult, GamblingError>> WofAsync(ulong userId, long amount);
Task<OneOf<LuLaResult, GamblingError>> WofAsync(ulong userId, long amount);
Task<OneOf<BetrollResult, GamblingError>> BetRollAsync(ulong userId, long amount);
Task<OneOf<BetflipResult, GamblingError>> BetFlipAsync(ulong userId, long amount, byte guess);
Task<OneOf<SlotResult, GamblingError>> SlotAsync(ulong userId, long amount);

View File

@@ -19,7 +19,7 @@ public sealed class NewGamblingService : IGamblingService, INService
// todo input checks
// todo ladder of fortune
public async Task<OneOf<WofResult, GamblingError>> WofAsync(ulong userId, long amount)
public async Task<OneOf<LuLaResult, GamblingError>> WofAsync(ulong userId, long amount)
{
if (amount < 0)
throw new ArgumentOutOfRangeException(nameof(amount));
@@ -34,7 +34,7 @@ public sealed class NewGamblingService : IGamblingService, INService
}
}
var game = new WofGame(_bcs.Data.WheelOfFortune.Multipliers);
var game = new LulaGame(_bcs.Data.LuckyLadder.Multipliers);
var result = game.Spin(amount);
var won = (long)result.Won;

View File

@@ -94,162 +94,6 @@ public partial class Games
await ReplyErrorLocalizedAsync(strs.trivia_none);
}
private void RegisterEvents(TriviaGame trivia)
{
IEmbedBuilder? questionEmbed = null;
IUserMessage? questionMessage = null;
var showHowToQuit = false;
trivia.OnQuestion += async (_, question) =>
{
try
{
questionEmbed = _eb.Create()
.WithOkColor()
.WithTitle(GetText(strs.trivia_game))
.AddField(GetText(strs.category), question.Category)
.AddField(GetText(strs.question), question.Question);
showHowToQuit = !showHowToQuit;
if (showHowToQuit)
questionEmbed.WithFooter(GetText(strs.trivia_quit($"{prefix}tq")));
if (Uri.IsWellFormedUriString(question.ImageUrl, UriKind.Absolute))
questionEmbed.WithImageUrl(question.ImageUrl);
questionMessage = await ctx.Channel.EmbedAsync(questionEmbed);
}
catch (HttpException ex) when (ex.HttpCode is HttpStatusCode.NotFound
or HttpStatusCode.Forbidden
or HttpStatusCode.BadRequest)
{
Log.Warning("Unable to send trivia questions. Stopping immediately");
trivia.Stop();
}
catch (Exception ex)
{
Log.Warning(ex, "Error sending trivia embed");
await Task.Delay(2000);
}
};
trivia.OnHint += async (_, question) =>
{
try
{
if (questionMessage is null)
{
trivia.Stop();
return;
}
if (questionEmbed is not null)
await questionMessage.ModifyAsync(m
=> m.Embed = questionEmbed.WithFooter(question.GetHint()).Build());
}
catch (HttpException ex) when (ex.HttpCode is HttpStatusCode.NotFound
or HttpStatusCode.Forbidden)
{
Log.Warning("Unable to edit message to show hint. Stopping trivia");
trivia.Stop();
}
catch (Exception ex) { Log.Warning(ex, "Error editing triva message"); }
};
trivia.OnGuess += async (_, user, question, isWin) =>
{
try
{
var embed = _eb.Create()
.WithOkColor()
.WithTitle(GetText(strs.trivia_game))
.WithDescription(GetText(strs.trivia_win(user.Name,
Format.Bold(question.Answer))));
if (Uri.IsWellFormedUriString(question.AnswerImageUrl, UriKind.Absolute))
embed.WithImageUrl(question.AnswerImageUrl);
if (isWin)
{
await ctx.Channel.EmbedAsync(embed);
var reward = _gamesConfig.Data.Trivia.CurrencyReward;
if (reward > 0)
await _cs.AddAsync(user.Id, reward, new("trivia", "win"));
return;
}
embed.WithDescription(GetText(strs.trivia_guess(user.Name,
Format.Bold(question.Answer))));
await ctx.Channel.EmbedAsync(embed);
}
catch
{
// ignored
}
};
trivia.OnEnded += async (game) =>
{
try
{
await ctx.Channel.EmbedAsync(_eb.Create(ctx)
.WithOkColor()
.WithAuthor(GetText(strs.trivia_ended))
.WithTitle(GetText(strs.leaderboard))
.WithDescription(GetLeaderboardString(game)));
}
catch
{
// ignored
}
finally
{
_service.RunningTrivias.TryRemove(ctx.Guild.Id, out _);
}
};
trivia.OnStats += async (game) =>
{
try
{
await SendConfirmAsync(GetText(strs.leaderboard), GetLeaderboardString(game));
}
catch
{
// ignored
}
};
trivia.OnTimeout += async (_, question) =>
{
try
{
var embed = _eb.Create()
.WithErrorColor()
.WithTitle(GetText(strs.trivia_game))
.WithDescription(GetText(strs.trivia_times_up(Format.Bold(question.Answer))));
if (Uri.IsWellFormedUriString(question.AnswerImageUrl, UriKind.Absolute))
embed.WithImageUrl(question.AnswerImageUrl);
await ctx.Channel.EmbedAsync(embed);
}
catch
{
// ignored
}
};
}
private string GetLeaderboardString(TriviaGame tg)
{
@@ -261,5 +105,175 @@ public partial class Games
return sb.ToString();
}
private IEmbedBuilder? questionEmbed = null;
private IUserMessage? questionMessage = null;
private bool showHowToQuit = false;
private void RegisterEvents(TriviaGame trivia)
{
trivia.OnQuestion += OnTriviaOnOnQuestion;
trivia.OnHint += OnTriviaOnOnHint;
trivia.OnGuess += OnTriviaOnOnGuess;
trivia.OnEnded += OnTriviaOnOnEnded;
trivia.OnStats += OnTriviaOnOnStats;
trivia.OnTimeout += OnTriviaOnOnTimeout;
}
private void UnregisterEvents(TriviaGame trivia)
{
trivia.OnQuestion -= OnTriviaOnOnQuestion;
trivia.OnHint -= OnTriviaOnOnHint;
trivia.OnGuess -= OnTriviaOnOnGuess;
trivia.OnEnded -= OnTriviaOnOnEnded;
trivia.OnStats -= OnTriviaOnOnStats;
trivia.OnTimeout -= OnTriviaOnOnTimeout;
}
private async Task OnTriviaOnOnHint(TriviaGame game, TriviaQuestion question)
{
try
{
if (questionMessage is null)
{
game.Stop();
return;
}
if (questionEmbed is not null)
await questionMessage.ModifyAsync(m => m.Embed = questionEmbed.WithFooter(question.GetHint()).Build());
}
catch (HttpException ex) when (ex.HttpCode is HttpStatusCode.NotFound or HttpStatusCode.Forbidden)
{
Log.Warning("Unable to edit message to show hint. Stopping trivia");
game.Stop();
}
catch (Exception ex)
{
Log.Warning(ex, "Error editing triva message");
}
}
private async Task OnTriviaOnOnQuestion(TriviaGame game, TriviaQuestion question)
{
try
{
questionEmbed = _eb.Create()
.WithOkColor()
.WithTitle(GetText(strs.trivia_game))
.AddField(GetText(strs.category), question.Category)
.AddField(GetText(strs.question), question.Question);
showHowToQuit = !showHowToQuit;
if (showHowToQuit)
questionEmbed.WithFooter(GetText(strs.trivia_quit($"{prefix}tq")));
if (Uri.IsWellFormedUriString(question.ImageUrl, UriKind.Absolute))
questionEmbed.WithImageUrl(question.ImageUrl);
questionMessage = await ctx.Channel.EmbedAsync(questionEmbed);
}
catch (HttpException ex) when (ex.HttpCode is HttpStatusCode.NotFound or HttpStatusCode.Forbidden or HttpStatusCode.BadRequest)
{
Log.Warning("Unable to send trivia questions. Stopping immediately");
game.Stop();
}
catch (Exception ex)
{
Log.Warning(ex, "Error sending trivia embed");
await Task.Delay(2000);
}
}
private async Task OnTriviaOnOnTimeout(TriviaGame _, TriviaQuestion question)
{
try
{
var embed = _eb.Create()
.WithErrorColor()
.WithTitle(GetText(strs.trivia_game))
.WithDescription(GetText(strs.trivia_times_up(Format.Bold(question.Answer))));
if (Uri.IsWellFormedUriString(question.AnswerImageUrl, UriKind.Absolute))
embed.WithImageUrl(question.AnswerImageUrl);
await ctx.Channel.EmbedAsync(embed);
}
catch
{
// ignored
}
}
private async Task OnTriviaOnOnStats(TriviaGame game)
{
try
{
await SendConfirmAsync(GetText(strs.leaderboard), GetLeaderboardString(game));
}
catch
{
// ignored
}
}
private async Task OnTriviaOnOnEnded(TriviaGame game)
{
try
{
await ctx.Channel.EmbedAsync(_eb.Create(ctx)
.WithOkColor()
.WithAuthor(GetText(strs.trivia_ended))
.WithTitle(GetText(strs.leaderboard))
.WithDescription(GetLeaderboardString(game)));
}
catch
{
// ignored
}
finally
{
_service.RunningTrivias.TryRemove(ctx.Guild.Id, out _);
}
UnregisterEvents(game);
await Task.Delay(1000);
}
private async Task OnTriviaOnOnGuess(TriviaGame _, TriviaUser user, TriviaQuestion question, bool isWin)
{
try
{
var embed = _eb.Create()
.WithOkColor()
.WithTitle(GetText(strs.trivia_game))
.WithDescription(GetText(strs.trivia_win(user.Name,
Format.Bold(question.Answer))));
if (Uri.IsWellFormedUriString(question.AnswerImageUrl, UriKind.Absolute))
embed.WithImageUrl(question.AnswerImageUrl);
if (isWin)
{
await ctx.Channel.EmbedAsync(embed);
var reward = _gamesConfig.Data.Trivia.CurrencyReward;
if (reward > 0)
await _cs.AddAsync(user.Id, reward, new("trivia", "win"));
return;
}
embed.WithDescription(GetText(strs.trivia_guess(user.Name,
Format.Bold(question.Answer))));
await ctx.Channel.EmbedAsync(embed);
}
catch
{
// ignored
}
}
}
}