mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-04 00:34:26 -05:00 
			
		
		
		
	Work on porting over Ayu gambling command rewrites
This commit is contained in:
		@@ -8,12 +8,356 @@ using SixLabors.ImageSharp.Drawing.Processing;
 | 
			
		||||
using SixLabors.ImageSharp.PixelFormats;
 | 
			
		||||
using SixLabors.ImageSharp.Processing;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Nadeko.Common;
 | 
			
		||||
using Grpc.Core;
 | 
			
		||||
using NadekoBot.Modules.Gambling.WheelOfFortune;
 | 
			
		||||
using NadekoBot.Services.Currency;
 | 
			
		||||
using Color = SixLabors.ImageSharp.Color;
 | 
			
		||||
using Image = SixLabors.ImageSharp.Image;
 | 
			
		||||
using OneOf;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Gambling;
 | 
			
		||||
 | 
			
		||||
public enum SlotError
 | 
			
		||||
{
 | 
			
		||||
    InsufficientFunds,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public enum WofError
 | 
			
		||||
{
 | 
			
		||||
    InsufficientFunds,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public interface ISlotService
 | 
			
		||||
{
 | 
			
		||||
    ValueTask<OneOf<SlotResult, SlotError>> PullAsync(ulong userId, long amount);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public record struct WofRequest(ulong UserId, long Amount);
 | 
			
		||||
 | 
			
		||||
public record struct BetrollRequest(ulong UserId, long Amount);
 | 
			
		||||
 | 
			
		||||
public sealed class DefaultSlotService : INService
 | 
			
		||||
{
 | 
			
		||||
    private readonly GamblingConfigService _bcs;
 | 
			
		||||
    private readonly ICurrencyService _cs;
 | 
			
		||||
    // public ValueTask<OneOf<SlotResult, SlotError>> PullAsync(ulong userId, long amount)
 | 
			
		||||
    // {
 | 
			
		||||
    //     
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    public DefaultSlotService(GamblingConfigService bcs, ICurrencyService cs)
 | 
			
		||||
    {
 | 
			
		||||
        _bcs = bcs;
 | 
			
		||||
        _cs = cs;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public async Task<OneOf<WofResult, WofError>> Wof(WofRequest request, ServerCallContext context)
 | 
			
		||||
    {
 | 
			
		||||
        var isTakeSuccess = await _cs.RemoveAsync(request.UserId, request.Amount, new TxData("wof", "bet"));
 | 
			
		||||
 | 
			
		||||
        if (!isTakeSuccess)
 | 
			
		||||
        {
 | 
			
		||||
            return WofError.InsufficientFunds;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var game = new WheelOfFortuneGame(_bcs.Data.WheelOfFortune.Multipliers);
 | 
			
		||||
        var result = game.Spin(request.Amount);
 | 
			
		||||
 | 
			
		||||
        if (result.Amount > 0)
 | 
			
		||||
        {
 | 
			
		||||
            await _cs.AddAsync(request.UserId, result.Amount, new("wof", "win"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public override async Task<OneOf<>> BetRoll(BetRollRequest request, ServerCallContext context)
 | 
			
		||||
    {
 | 
			
		||||
        var takeRes = await _currency.TransferCurrencyAsync(new TransferCurrencyRequest
 | 
			
		||||
        {
 | 
			
		||||
            Amount = request.Amount,
 | 
			
		||||
            Type = "bet-roll",
 | 
			
		||||
            Subtype = "bet",
 | 
			
		||||
            FromId = request.UserId,
 | 
			
		||||
            ToId = 0,
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (!takeRes.Success)
 | 
			
		||||
        {
 | 
			
		||||
            return new BetRollReply
 | 
			
		||||
            {
 | 
			
		||||
                Error = GamblingError.NotEnough
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var game = new Betroll(_config.Data.BetRoll);
 | 
			
		||||
        var result = game.Roll();
 | 
			
		||||
 | 
			
		||||
        if (result.Multiplier > 0)
 | 
			
		||||
        {
 | 
			
		||||
            var won = (long)(request.Amount * result.Multiplier);
 | 
			
		||||
 | 
			
		||||
            await _currency.GrantToUserAsync(new GrantToUserRequest
 | 
			
		||||
            {
 | 
			
		||||
                Amount = won,
 | 
			
		||||
                Type = "bet-roll",
 | 
			
		||||
                Subtype = "won",
 | 
			
		||||
                UserId = request.UserId,
 | 
			
		||||
                GranterId = 0,
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return new BetRollReply
 | 
			
		||||
            {
 | 
			
		||||
                WonAmount = won,
 | 
			
		||||
                Multiplier = result.Multiplier,
 | 
			
		||||
                Roll = result.Roll,
 | 
			
		||||
                Threshold = result.Threshold,
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new BetRollReply
 | 
			
		||||
        {
 | 
			
		||||
            WonAmount = 0,
 | 
			
		||||
            Multiplier = result.Multiplier,
 | 
			
		||||
            Roll = result.Roll,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // public override async Task<BetFlipReply> BetFlip(BetFlipRequest request, ServerCallContext context)
 | 
			
		||||
    // {
 | 
			
		||||
    //  var takeRes = await _currency.TransferCurrencyAsync(new TransferCurrencyRequest
 | 
			
		||||
    //  {
 | 
			
		||||
    //      Amount = request.Amount,
 | 
			
		||||
    //      Type = "bet-flip",
 | 
			
		||||
    //      Subtype = "bet",
 | 
			
		||||
    //      FromId = request.UserId,
 | 
			
		||||
    //      ToId = 0,
 | 
			
		||||
    //  });
 | 
			
		||||
    //
 | 
			
		||||
    //  if (!takeRes.Success)
 | 
			
		||||
    //  {
 | 
			
		||||
    //      return new BetFlipReply
 | 
			
		||||
    //      {
 | 
			
		||||
    //          Error = GamblingError.NotEnough
 | 
			
		||||
    //      };
 | 
			
		||||
    //  }
 | 
			
		||||
    //
 | 
			
		||||
    //  var roll = _rng.Next(0, 1000) <= 499;
 | 
			
		||||
    //  long won = 0;
 | 
			
		||||
    //
 | 
			
		||||
    //  if (roll == request.Guess)
 | 
			
		||||
    //  {
 | 
			
		||||
    //      won = (long) (_config.Data.Multipliers.BetFlip * request.Amount);
 | 
			
		||||
    //
 | 
			
		||||
    //      await _currency.GrantToUserAsync(new GrantToUserRequest
 | 
			
		||||
    //      {
 | 
			
		||||
    //          Amount = won,
 | 
			
		||||
    //          Type = "bet-flip",
 | 
			
		||||
    //          Subtype = "won",
 | 
			
		||||
    //          UserId = request.UserId,
 | 
			
		||||
    //          GranterId = 0,
 | 
			
		||||
    //      });
 | 
			
		||||
    //  }
 | 
			
		||||
    //
 | 
			
		||||
    //
 | 
			
		||||
    //  return new BetFlipReply
 | 
			
		||||
    //  {
 | 
			
		||||
    //      Result = roll
 | 
			
		||||
    //          ? BetFlipReply.Types.Side.Heads
 | 
			
		||||
    //          : BetFlipReply.Types.Side.Tails,
 | 
			
		||||
    //      WonAmount = won
 | 
			
		||||
    //  };
 | 
			
		||||
    // }
 | 
			
		||||
    //
 | 
			
		||||
    // public override Task<FlipReply> Flip(FlipRequest request, ServerCallContext context)
 | 
			
		||||
    // {
 | 
			
		||||
    //  if (request.Count <= 0)
 | 
			
		||||
    //      throw new RpcException(new Status(StatusCode.InvalidArgument, "Count has to be greater than 0."));
 | 
			
		||||
    //
 | 
			
		||||
    //  var results = Enumerable.Range(0, request.Count)
 | 
			
		||||
    //      .Select(x => (FlipReply.Types.Roll) _rng.Next(0, 2));
 | 
			
		||||
    //
 | 
			
		||||
    //  var toReturn = new FlipReply();
 | 
			
		||||
    //  toReturn.Rolls.AddRange(results);
 | 
			
		||||
    //  return Task.FromResult(toReturn);
 | 
			
		||||
    // }
 | 
			
		||||
    //
 | 
			
		||||
    // public override async Task<SlotResponse> Slot(SlotRequest request, ServerCallContext context)
 | 
			
		||||
    // {
 | 
			
		||||
    //  var takeRes = await _currency.TransferCurrencyAsync(new TransferCurrencyRequest
 | 
			
		||||
    //  {
 | 
			
		||||
    //      Amount = request.Amount,
 | 
			
		||||
    //      Type = "slot",
 | 
			
		||||
    //      Subtype = "bet",
 | 
			
		||||
    //      FromId = request.UserId,
 | 
			
		||||
    //      ToId = 0,
 | 
			
		||||
    //  });
 | 
			
		||||
    //
 | 
			
		||||
    //  if (!takeRes.Success)
 | 
			
		||||
    //  {
 | 
			
		||||
    //      return new SlotResponse
 | 
			
		||||
    //      {
 | 
			
		||||
    //          Error = GamblingError.NotEnough
 | 
			
		||||
    //      };
 | 
			
		||||
    //  }
 | 
			
		||||
    //
 | 
			
		||||
    //  var game = new SlotGame();
 | 
			
		||||
    //  var result = game.Spin();
 | 
			
		||||
    //  long won = 0;
 | 
			
		||||
    //
 | 
			
		||||
    //  if (result.Multiplier > 0)
 | 
			
		||||
    //  {
 | 
			
		||||
    //      won = (long) (result.Multiplier * request.Amount);
 | 
			
		||||
    //
 | 
			
		||||
    //      await _currency.GrantToUserAsync(new GrantToUserRequest
 | 
			
		||||
    //      {
 | 
			
		||||
    //          Amount = won,
 | 
			
		||||
    //          Type = "slot",
 | 
			
		||||
    //          Subtype = "won",
 | 
			
		||||
    //          UserId = request.UserId,
 | 
			
		||||
    //          GranterId = 0,
 | 
			
		||||
    //      });
 | 
			
		||||
    //  }
 | 
			
		||||
    //
 | 
			
		||||
    //  var toReturn = new SlotResponse
 | 
			
		||||
    //  {
 | 
			
		||||
    //      Multiplier = result.Multiplier,
 | 
			
		||||
    //      Won = won,
 | 
			
		||||
    //  };
 | 
			
		||||
    //
 | 
			
		||||
    //  toReturn.Rolls.AddRange(result.Rolls);
 | 
			
		||||
    //
 | 
			
		||||
    //  return toReturn;
 | 
			
		||||
    // }
 | 
			
		||||
    //
 | 
			
		||||
    // private readonly ConcurrentDictionary<ulong, Deck> _decks = new ConcurrentDictionary<ulong, Deck>();
 | 
			
		||||
    //
 | 
			
		||||
    // public override Task<DeckShuffleReply> DeckShuffle(DeckShuffleRequest request, ServerCallContext context)
 | 
			
		||||
    // {
 | 
			
		||||
    //  _decks.AddOrUpdate(request.Id, new Deck(), (key, old) => new Deck());
 | 
			
		||||
    //  return Task.FromResult(new DeckShuffleReply { });
 | 
			
		||||
    // }
 | 
			
		||||
    //
 | 
			
		||||
    // public override Task<DeckDrawReply> DeckDraw(DeckDrawRequest request, ServerCallContext context)
 | 
			
		||||
    // {
 | 
			
		||||
    //  if (request.Count < 1 || request.Count > 10)
 | 
			
		||||
    //      throw new ArgumentOutOfRangeException(nameof(request.Id));
 | 
			
		||||
    //
 | 
			
		||||
    //  var deck = request.UseNew
 | 
			
		||||
    //      ? new Deck()
 | 
			
		||||
    //      : _decks.GetOrAdd(request.Id, new Deck());
 | 
			
		||||
    //
 | 
			
		||||
    //  var list = new List<Deck.Card>(request.Count);
 | 
			
		||||
    //  for (int i = 0; i < request.Count; i++)
 | 
			
		||||
    //  {
 | 
			
		||||
    //      var card = deck.DrawNoRestart();
 | 
			
		||||
    //      if (card is null)
 | 
			
		||||
    //      {
 | 
			
		||||
    //          if (i == 0)
 | 
			
		||||
    //          {
 | 
			
		||||
    //              deck.Restart();
 | 
			
		||||
    //              list.Add(deck.DrawNoRestart());
 | 
			
		||||
    //              continue;
 | 
			
		||||
    //          }
 | 
			
		||||
    //
 | 
			
		||||
    //          break;
 | 
			
		||||
    //      }
 | 
			
		||||
    //
 | 
			
		||||
    //      list.Add(card);
 | 
			
		||||
    //  }
 | 
			
		||||
    //
 | 
			
		||||
    //  // todo 3.2 should replace all "placeholder" words in command strings with a link to the placeholder list explanation
 | 
			
		||||
    //  var cards = list
 | 
			
		||||
    //      .Select(x => new Card
 | 
			
		||||
    //      {
 | 
			
		||||
    //          Name = x.ToString().ToLowerInvariant().Replace(' ', '_'),
 | 
			
		||||
    //          Number = x.Number,
 | 
			
		||||
    //          Suit = (CardSuit) x.Suit
 | 
			
		||||
    //      });
 | 
			
		||||
    //
 | 
			
		||||
    //  var toReturn = new DeckDrawReply();
 | 
			
		||||
    //  toReturn.Cards.AddRange(cards);
 | 
			
		||||
    //
 | 
			
		||||
    //  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 partial class Gambling
 | 
			
		||||
{
 | 
			
		||||
    [Group]
 | 
			
		||||
@@ -220,50 +564,50 @@ public partial class Gambling
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
        public sealed class SlotMachine
 | 
			
		||||
public sealed class SlotMachine
 | 
			
		||||
{
 | 
			
		||||
    public const int MAX_VALUE = 5;
 | 
			
		||||
 | 
			
		||||
    private static readonly List<Func<int[], int>> _winningCombos = new()
 | 
			
		||||
    {
 | 
			
		||||
        //three flowers
 | 
			
		||||
        arr => arr.All(a => a == MAX_VALUE) ? 30 : 0,
 | 
			
		||||
        //three of the same
 | 
			
		||||
        arr => !arr.Any(a => a != arr[0]) ? 10 : 0,
 | 
			
		||||
        //two flowers
 | 
			
		||||
        arr => arr.Count(a => a == MAX_VALUE) == 2 ? 4 : 0,
 | 
			
		||||
        //one flower
 | 
			
		||||
        arr => arr.Any(a => a == MAX_VALUE) ? 1 : 0
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    public static SlotResult Pull()
 | 
			
		||||
    {
 | 
			
		||||
        var numbers = new int[3];
 | 
			
		||||
        for (var i = 0; i < numbers.Length; i++)
 | 
			
		||||
            numbers[i] = new NadekoRandom().Next(0, MAX_VALUE + 1);
 | 
			
		||||
        var multi = 0;
 | 
			
		||||
        foreach (var t in _winningCombos)
 | 
			
		||||
        {
 | 
			
		||||
            public const int MAX_VALUE = 5;
 | 
			
		||||
 | 
			
		||||
            private static readonly List<Func<int[], int>> _winningCombos = new()
 | 
			
		||||
            {
 | 
			
		||||
                //three flowers
 | 
			
		||||
                arr => arr.All(a => a == MAX_VALUE) ? 30 : 0,
 | 
			
		||||
                //three of the same
 | 
			
		||||
                arr => !arr.Any(a => a != arr[0]) ? 10 : 0,
 | 
			
		||||
                //two flowers
 | 
			
		||||
                arr => arr.Count(a => a == MAX_VALUE) == 2 ? 4 : 0,
 | 
			
		||||
                //one flower
 | 
			
		||||
                arr => arr.Any(a => a == MAX_VALUE) ? 1 : 0
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            public static SlotResult Pull()
 | 
			
		||||
            {
 | 
			
		||||
                var numbers = new int[3];
 | 
			
		||||
                for (var i = 0; i < numbers.Length; i++)
 | 
			
		||||
                    numbers[i] = new NadekoRandom().Next(0, MAX_VALUE + 1);
 | 
			
		||||
                var multi = 0;
 | 
			
		||||
                foreach (var t in _winningCombos)
 | 
			
		||||
                {
 | 
			
		||||
                    multi = t(numbers);
 | 
			
		||||
                    if (multi != 0)
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return new(numbers, multi);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public struct SlotResult
 | 
			
		||||
            {
 | 
			
		||||
                public int[] Numbers { get; }
 | 
			
		||||
                public int Multiplier { get; }
 | 
			
		||||
 | 
			
		||||
                public SlotResult(int[] nums, int multi)
 | 
			
		||||
                {
 | 
			
		||||
                    Numbers = nums;
 | 
			
		||||
                    Multiplier = multi;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            multi = t(numbers);
 | 
			
		||||
            if (multi != 0)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new(numbers, multi);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public struct SlotResult
 | 
			
		||||
{
 | 
			
		||||
    public int[] Numbers { get; }
 | 
			
		||||
    public int Multiplier { get; }
 | 
			
		||||
 | 
			
		||||
    public SlotResult(int[] nums, int multi)
 | 
			
		||||
    {
 | 
			
		||||
        Numbers = nums;
 | 
			
		||||
        Multiplier = multi;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								src/NadekoBot/Modules/Gambling/Wheel/WheelOfFortune.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/NadekoBot/Modules/Gambling/Wheel/WheelOfFortune.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
namespace NadekoBot.Modules.Gambling.WheelOfFortune;
 | 
			
		||||
 | 
			
		||||
public sealed class WheelOfFortuneGame
 | 
			
		||||
{
 | 
			
		||||
    public static IReadOnlyList<decimal> DEFAULT_MULTIPLIERS = new[] { 1.7M, 1.5M, 0.2M, 0.1M, 0.3M, 0.5M, 1.2M, 2.4M };
 | 
			
		||||
    
 | 
			
		||||
    private readonly IReadOnlyList<decimal> _multipliers;
 | 
			
		||||
    private readonly NadekoRandom _rng;
 | 
			
		||||
 | 
			
		||||
    public WheelOfFortuneGame(IReadOnlyList<decimal> multipliers)
 | 
			
		||||
    {
 | 
			
		||||
        _multipliers = multipliers;
 | 
			
		||||
        _rng = new();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public WheelOfFortuneGame() : this(DEFAULT_MULTIPLIERS)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public WofResult Spin(long bet)
 | 
			
		||||
    {
 | 
			
		||||
        var result = _rng.Next(0, _multipliers.Count);
 | 
			
		||||
 | 
			
		||||
        var multi = _multipliers[result];
 | 
			
		||||
        var amount = (long)(bet * multi);
 | 
			
		||||
 | 
			
		||||
        return new()
 | 
			
		||||
        {
 | 
			
		||||
            Index = result,
 | 
			
		||||
            Multiplier = multi,
 | 
			
		||||
            Amount = amount
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								src/NadekoBot/Modules/Gambling/Wheel/WofResult.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/NadekoBot/Modules/Gambling/Wheel/WofResult.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
namespace NadekoBot.Modules.Gambling.WheelOfFortune;
 | 
			
		||||
 | 
			
		||||
public readonly struct WofResult
 | 
			
		||||
{
 | 
			
		||||
    public int Index { get; init; }
 | 
			
		||||
    public decimal Multiplier { get; init; }
 | 
			
		||||
    public long Amount { get; init; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
namespace NadekoBot.Modules.Gambling.Common.WheelOfFortune;
 | 
			
		||||
 | 
			
		||||
public class WheelOfFortuneGame
 | 
			
		||||
{
 | 
			
		||||
    private readonly NadekoRandom _rng;
 | 
			
		||||
    private readonly ICurrencyService _cs;
 | 
			
		||||
    private readonly long _bet;
 | 
			
		||||
    private readonly GamblingConfig _config;
 | 
			
		||||
    private readonly ulong _userId;
 | 
			
		||||
 | 
			
		||||
    public WheelOfFortuneGame(
 | 
			
		||||
        ulong userId,
 | 
			
		||||
        long bet,
 | 
			
		||||
        GamblingConfig config,
 | 
			
		||||
        ICurrencyService cs)
 | 
			
		||||
    {
 | 
			
		||||
        _rng = new();
 | 
			
		||||
        _cs = cs;
 | 
			
		||||
        _bet = bet;
 | 
			
		||||
        _config = config;
 | 
			
		||||
        _userId = userId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public async Task<Result> SpinAsync()
 | 
			
		||||
    {
 | 
			
		||||
        var result = _rng.Next(0, _config.WheelOfFortune.Multipliers.Length);
 | 
			
		||||
 | 
			
		||||
        var amount = (long)(_bet * _config.WheelOfFortune.Multipliers[result]);
 | 
			
		||||
 | 
			
		||||
        if (amount > 0)
 | 
			
		||||
            await _cs.AddAsync(_userId, amount, new("wheel", "win"));
 | 
			
		||||
 | 
			
		||||
        return new()
 | 
			
		||||
        {
 | 
			
		||||
            Index = result,
 | 
			
		||||
            Amount = amount
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class Result
 | 
			
		||||
    {
 | 
			
		||||
        public int Index { get; set; }
 | 
			
		||||
        public long Amount { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,7 +6,7 @@ public class Betroll
 | 
			
		||||
    private readonly IOrderedEnumerable<BetRollPair> _thresholdPairs;
 | 
			
		||||
    private readonly Random _rng;
 | 
			
		||||
 | 
			
		||||
    public Betroll(BetRollConfig settings)
 | 
			
		||||
    public Betroll(IReadOnlyList<long> pairs)
 | 
			
		||||
    {
 | 
			
		||||
        _thresholdPairs = settings.Pairs.OrderByDescending(x => x.WhenAbove);
 | 
			
		||||
        _rng = new();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user