mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-04 00:34:26 -05:00 
			
		
		
		
	Moved .rps to the new service, reimplemented logic, fixed an unknown bug with 0 amount (?!)
This commit is contained in:
		@@ -13,6 +13,7 @@ using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System.Collections.Immutable;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Nadeko.Econ.Gambling.Rps;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Gambling;
 | 
			
		||||
 | 
			
		||||
@@ -759,65 +760,72 @@ public partial class Gambling : GamblingModule<GamblingService>
 | 
			
		||||
            opts.Clean);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum InputRpsPick : byte
 | 
			
		||||
    {
 | 
			
		||||
        R = 0,
 | 
			
		||||
        Rock = 0,
 | 
			
		||||
        Rocket = 0,
 | 
			
		||||
        P = 1,
 | 
			
		||||
        Paper = 1,
 | 
			
		||||
        Paperclip = 1,
 | 
			
		||||
        S = 2,
 | 
			
		||||
        Scissors = 2
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // todo check if trivia is being disposed
 | 
			
		||||
    [Cmd]
 | 
			
		||||
    public async partial Task Rps(RpsPick pick, ShmartNumber amount = default)
 | 
			
		||||
    public async partial Task Rps(InputRpsPick pick, ShmartNumber amount = default)
 | 
			
		||||
    {
 | 
			
		||||
        if (!await CheckBetOptional(amount) || amount == 1)
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        string GetRpsPick(RpsPick p)
 | 
			
		||||
        static string GetRpsPick(InputRpsPick p)
 | 
			
		||||
        {
 | 
			
		||||
            switch (p)
 | 
			
		||||
            {
 | 
			
		||||
                case RpsPick.R:
 | 
			
		||||
                case InputRpsPick.R:
 | 
			
		||||
                    return "🚀";
 | 
			
		||||
                case RpsPick.P:
 | 
			
		||||
                case InputRpsPick.P:
 | 
			
		||||
                    return "📎";
 | 
			
		||||
                default:
 | 
			
		||||
                    return "✂️";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (!await CheckBetOptional(amount) || amount == 1)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        var embed = _eb.Create();
 | 
			
		||||
        var res = await _gs.RpsAsync(ctx.User.Id, amount, (byte)pick);
 | 
			
		||||
 | 
			
		||||
        var nadekoPick = (RpsPick)new NadekoRandom().Next(0, 3);
 | 
			
		||||
 | 
			
		||||
        if (amount > 0)
 | 
			
		||||
        if (!res.TryPickT0(out var result, out _))
 | 
			
		||||
        {
 | 
			
		||||
            if (!await _cs.RemoveAsync(ctx.User.Id, amount, new("rps", "bet")))
 | 
			
		||||
            {
 | 
			
		||||
                await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        var embed = _eb.Create();
 | 
			
		||||
        
 | 
			
		||||
        string msg;
 | 
			
		||||
        if (pick == nadekoPick)
 | 
			
		||||
        if (result.Result == RpsResultType.Draw)
 | 
			
		||||
        {
 | 
			
		||||
            await _cs.AddAsync(ctx.User.Id, amount, new("rps", "draw"));
 | 
			
		||||
            embed.WithOkColor();
 | 
			
		||||
            msg = GetText(strs.rps_draw(GetRpsPick(pick)));
 | 
			
		||||
        }
 | 
			
		||||
        else if ((pick == RpsPick.Paper && nadekoPick == RpsPick.Rock)
 | 
			
		||||
                 || (pick == RpsPick.Rock && nadekoPick == RpsPick.Scissors)
 | 
			
		||||
                 || (pick == RpsPick.Scissors && nadekoPick == RpsPick.Paper))
 | 
			
		||||
        else if (result.Result == RpsResultType.Win)
 | 
			
		||||
        {
 | 
			
		||||
            amount = (long)(amount * Config.BetFlip.Multiplier);
 | 
			
		||||
            await _cs.AddAsync(ctx.User.Id, amount, new("rps", "win"));
 | 
			
		||||
            embed.WithOkColor();
 | 
			
		||||
            embed.AddField(GetText(strs.won), N(amount.Value));
 | 
			
		||||
            msg = GetText(strs.rps_win(ctx.User.Mention, GetRpsPick(pick), GetRpsPick(nadekoPick)));
 | 
			
		||||
            if((long)result.Won > 0)
 | 
			
		||||
                 embed.AddField(GetText(strs.won), N(amount.Value));
 | 
			
		||||
 | 
			
		||||
            msg = GetText(strs.rps_win(ctx.User.Mention,
 | 
			
		||||
                GetRpsPick(pick),
 | 
			
		||||
                GetRpsPick((InputRpsPick)result.ComputerPick)));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            embed.WithErrorColor();
 | 
			
		||||
            msg = GetText(strs.rps_win(ctx.Client.CurrentUser.Mention, GetRpsPick(nadekoPick), GetRpsPick(pick)));
 | 
			
		||||
            msg = GetText(strs.rps_win(ctx.Client.CurrentUser.Mention,
 | 
			
		||||
                GetRpsPick((InputRpsPick)result.ComputerPick),
 | 
			
		||||
                GetRpsPick(pick)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        embed.WithDescription(msg);
 | 
			
		||||
        embed
 | 
			
		||||
            .WithOkColor()
 | 
			
		||||
            .WithDescription(msg);
 | 
			
		||||
 | 
			
		||||
        await ctx.Channel.EmbedAsync(embed);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								src/NadekoBot/Modules/Gambling/InputRpsPick.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/NadekoBot/Modules/Gambling/InputRpsPick.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
namespace NadekoBot.Modules.Gambling;
 | 
			
		||||
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
namespace NadekoBot.Modules.Gambling;
 | 
			
		||||
 | 
			
		||||
public enum RpsPick
 | 
			
		||||
{
 | 
			
		||||
    R = 0,
 | 
			
		||||
    Rock = 0,
 | 
			
		||||
    Rocket = 0,
 | 
			
		||||
    P = 1,
 | 
			
		||||
    Paper = 1,
 | 
			
		||||
    Paperclip = 1,
 | 
			
		||||
    S = 2,
 | 
			
		||||
    Scissors = 2
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
using Nadeko.Econ.Gambling;
 | 
			
		||||
using Nadeko.Econ.Gambling.Rps;
 | 
			
		||||
using OneOf;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Gambling;
 | 
			
		||||
@@ -11,4 +12,5 @@ public interface IGamblingService
 | 
			
		||||
    Task<OneOf<BetflipResult, GamblingError>> BetFlipAsync(ulong userId, long amount, byte guess);
 | 
			
		||||
    Task<OneOf<SlotResult, GamblingError>> SlotAsync(ulong userId, long amount);
 | 
			
		||||
    Task<FlipResult[]> FlipAsync(int count);
 | 
			
		||||
    Task<OneOf<RpsResult, GamblingError>> RpsAsync(ulong userId, long amount, byte pick);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
using Nadeko.Econ.Gambling;
 | 
			
		||||
using Nadeko.Econ.Gambling.Rps;
 | 
			
		||||
using NadekoBot.Modules.Gambling.Services;
 | 
			
		||||
using OneOf;
 | 
			
		||||
 | 
			
		||||
@@ -20,11 +21,17 @@ public sealed class NewGamblingService : IGamblingService, INService
 | 
			
		||||
    // todo ladder of fortune
 | 
			
		||||
    public async Task<OneOf<WofResult, GamblingError>> WofAsync(ulong userId, long amount)
 | 
			
		||||
    {
 | 
			
		||||
        var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("wof", "bet"));
 | 
			
		||||
 | 
			
		||||
        if (!isTakeSuccess)
 | 
			
		||||
        if (amount < 0)
 | 
			
		||||
            throw new ArgumentOutOfRangeException(nameof(amount));
 | 
			
		||||
        
 | 
			
		||||
        if (amount > 0)
 | 
			
		||||
        {
 | 
			
		||||
            return GamblingError.InsufficientFunds;
 | 
			
		||||
            var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("wof", "bet"));
 | 
			
		||||
 | 
			
		||||
            if (!isTakeSuccess)
 | 
			
		||||
            {
 | 
			
		||||
                return GamblingError.InsufficientFunds;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var game = new WofGame(_bcs.Data.WheelOfFortune.Multipliers);
 | 
			
		||||
@@ -41,16 +48,23 @@ public sealed class NewGamblingService : IGamblingService, INService
 | 
			
		||||
 | 
			
		||||
    public async Task<OneOf<BetrollResult, GamblingError>> BetRollAsync(ulong userId, long amount)
 | 
			
		||||
    {
 | 
			
		||||
        var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("betroll", "bet"));
 | 
			
		||||
        if (amount < 0)
 | 
			
		||||
            throw new ArgumentOutOfRangeException(nameof(amount));
 | 
			
		||||
 | 
			
		||||
        if (!isTakeSuccess)
 | 
			
		||||
        if (amount > 0)
 | 
			
		||||
        {
 | 
			
		||||
            return GamblingError.InsufficientFunds;
 | 
			
		||||
            var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("betroll", "bet"));
 | 
			
		||||
 | 
			
		||||
            if (!isTakeSuccess)
 | 
			
		||||
            {
 | 
			
		||||
                return GamblingError.InsufficientFunds;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var game = new BetrollGame(_bcs.Data.BetRoll.Pairs
 | 
			
		||||
            .Select(x => ((decimal)x.WhenAbove, (decimal)x.MultiplyBy))
 | 
			
		||||
            .Select(x => (x.WhenAbove, (decimal)x.MultiplyBy))
 | 
			
		||||
            .ToList());
 | 
			
		||||
        
 | 
			
		||||
        var result = game.Roll(amount);
 | 
			
		||||
        
 | 
			
		||||
        var won = (long)result.Won;
 | 
			
		||||
@@ -64,11 +78,17 @@ public sealed class NewGamblingService : IGamblingService, INService
 | 
			
		||||
 | 
			
		||||
    public async Task<OneOf<BetflipResult, GamblingError>> BetFlipAsync(ulong userId, long amount, byte guess)
 | 
			
		||||
    {
 | 
			
		||||
        var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("betflip", "bet"));
 | 
			
		||||
        if (amount < 0)
 | 
			
		||||
            throw new ArgumentOutOfRangeException(nameof(amount));
 | 
			
		||||
 | 
			
		||||
        if (!isTakeSuccess)
 | 
			
		||||
        if (amount > 0)
 | 
			
		||||
        {
 | 
			
		||||
            return GamblingError.InsufficientFunds;
 | 
			
		||||
            var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("betflip", "bet"));
 | 
			
		||||
 | 
			
		||||
            if (!isTakeSuccess)
 | 
			
		||||
            {
 | 
			
		||||
                return GamblingError.InsufficientFunds;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var game = new BetflipGame(_bcs.Data.BetFlip.Multiplier);
 | 
			
		||||
@@ -85,6 +105,9 @@ public sealed class NewGamblingService : IGamblingService, INService
 | 
			
		||||
 | 
			
		||||
    public async Task<OneOf<SlotResult, GamblingError>> SlotAsync(ulong userId, long amount)
 | 
			
		||||
    {
 | 
			
		||||
        if (amount < 0)
 | 
			
		||||
            throw new ArgumentOutOfRangeException(nameof(amount));
 | 
			
		||||
        
 | 
			
		||||
        if (amount > 0)
 | 
			
		||||
        {
 | 
			
		||||
            var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("slot", "bet"));
 | 
			
		||||
@@ -106,7 +129,7 @@ public sealed class NewGamblingService : IGamblingService, INService
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    public Task<FlipResult[]> FlipAsync(int count)
 | 
			
		||||
    {
 | 
			
		||||
        var game = new BetflipGame(0);
 | 
			
		||||
@@ -123,8 +146,8 @@ public sealed class NewGamblingService : IGamblingService, INService
 | 
			
		||||
        return Task.FromResult(results);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // todo deck draw black/white?
 | 
			
		||||
    
 | 
			
		||||
    // // todo deck draw black/white?
 | 
			
		||||
    //
 | 
			
		||||
    //
 | 
			
		||||
    // private readonly ConcurrentDictionary<ulong, Deck> _decks = new ConcurrentDictionary<ulong, Deck>();
 | 
			
		||||
    //
 | 
			
		||||
@@ -177,79 +200,41 @@ public sealed class NewGamblingService : IGamblingService, INService
 | 
			
		||||
    //  return Task.FromResult(toReturn);
 | 
			
		||||
    // }
 | 
			
		||||
    //
 | 
			
		||||
    // public override async Task<RpsReply> Rps(RpsRequest request, ServerCallContext context)
 | 
			
		||||
    // {
 | 
			
		||||
    //  if (request.Amount > 0)
 | 
			
		||||
    //  {
 | 
			
		||||
    //      var res = await _currency.TransferCurrencyAsync(new TransferCurrencyRequest
 | 
			
		||||
    //      {
 | 
			
		||||
    //          Amount = request.Amount,
 | 
			
		||||
    //          FromId = request.UserId,
 | 
			
		||||
    //          Type = "rps",
 | 
			
		||||
    //          Subtype = "bet",
 | 
			
		||||
    //      });
 | 
			
		||||
    //
 | 
			
		||||
    //      if (!res.Success)
 | 
			
		||||
    //      {
 | 
			
		||||
    //          return new RpsReply
 | 
			
		||||
    //          {
 | 
			
		||||
    //              Result = RpsReply.Types.ResultType.NotEnough
 | 
			
		||||
    //          };
 | 
			
		||||
    //      }
 | 
			
		||||
    //  }
 | 
			
		||||
    //
 | 
			
		||||
    //  var botPick = _rng.Next(0, 3);
 | 
			
		||||
    //  var userPick = (int) request.Pick;
 | 
			
		||||
    //
 | 
			
		||||
    //  if (botPick == userPick)
 | 
			
		||||
    //  {
 | 
			
		||||
    //      if (request.Amount > 0)
 | 
			
		||||
    //      {
 | 
			
		||||
    //          await _currency.GrantToUserAsync(new GrantToUserRequest
 | 
			
		||||
    //          {
 | 
			
		||||
    //              Amount = request.Amount,
 | 
			
		||||
    //              GranterId = 0,
 | 
			
		||||
    //              Type = "rps",
 | 
			
		||||
    //              Subtype = "draw",
 | 
			
		||||
    //              UserId = request.UserId,
 | 
			
		||||
    //          });
 | 
			
		||||
    //      }
 | 
			
		||||
    //
 | 
			
		||||
    //      return new RpsReply
 | 
			
		||||
    //      {
 | 
			
		||||
    //          BotPick = (RpsPick) botPick,
 | 
			
		||||
    //          WonAmount = request.Amount,
 | 
			
		||||
    //          Result = RpsReply.Types.ResultType.Draw
 | 
			
		||||
    //      };
 | 
			
		||||
    //  }
 | 
			
		||||
    //
 | 
			
		||||
    //  if ((botPick == 1 && userPick == 2) || (botPick == 2 && userPick == 0) || (botPick == 0 && userPick == 1))
 | 
			
		||||
    //  {
 | 
			
		||||
    //      if (request.Amount > 0)
 | 
			
		||||
    //      {
 | 
			
		||||
    //          await _currency.GrantToUserAsync(new GrantToUserRequest
 | 
			
		||||
    //          {
 | 
			
		||||
    //              Amount = (long) (request.Amount * 1.95f),
 | 
			
		||||
    //              GranterId = 0,
 | 
			
		||||
    //              Type = "rps",
 | 
			
		||||
    //              Subtype = "draw",
 | 
			
		||||
    //              UserId = request.UserId,
 | 
			
		||||
    //          });
 | 
			
		||||
    //      }
 | 
			
		||||
    //
 | 
			
		||||
    //      return new RpsReply
 | 
			
		||||
    //      {
 | 
			
		||||
    //          BotPick = (RpsPick) botPick,
 | 
			
		||||
    //          WonAmount = (long) (request.Amount * 1.95f),
 | 
			
		||||
    //          Result = RpsReply.Types.ResultType.Won
 | 
			
		||||
    //      };
 | 
			
		||||
    //  }
 | 
			
		||||
    //
 | 
			
		||||
    //  return new RpsReply
 | 
			
		||||
    //  {
 | 
			
		||||
    //      BotPick = (RpsPick) botPick,
 | 
			
		||||
    //      WonAmount = 0,
 | 
			
		||||
    //      Result = RpsReply.Types.ResultType.Lost
 | 
			
		||||
    //  };
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    public async Task<OneOf<RpsResult, GamblingError>> RpsAsync(ulong userId, long amount, byte pick)
 | 
			
		||||
    {
 | 
			
		||||
        if (amount < 0)
 | 
			
		||||
            throw new ArgumentOutOfRangeException(nameof(amount));
 | 
			
		||||
 | 
			
		||||
        if (pick > 2)
 | 
			
		||||
            throw new ArgumentOutOfRangeException(nameof(pick));
 | 
			
		||||
        
 | 
			
		||||
        if (amount > 0)
 | 
			
		||||
        {
 | 
			
		||||
            var isTakeSuccess = await _cs.RemoveAsync(userId, amount, new("rps", "bet"));
 | 
			
		||||
 | 
			
		||||
            if (!isTakeSuccess)
 | 
			
		||||
            {
 | 
			
		||||
                return GamblingError.InsufficientFunds;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var rps = new RpsGame();
 | 
			
		||||
        var result = rps.Play((RpsPick)pick, amount);
 | 
			
		||||
        
 | 
			
		||||
        var won = (long)result.Won;
 | 
			
		||||
        if (won > 0)
 | 
			
		||||
        {
 | 
			
		||||
            var extra = result.Result switch
 | 
			
		||||
            {
 | 
			
		||||
                RpsResultType.Draw => "draw",
 | 
			
		||||
                RpsResultType.Win => "win",
 | 
			
		||||
                _ => "lose"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            await _cs.AddAsync(userId, won, new("rps", extra));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user