Slots redesign nad images moved to images.yml

This commit is contained in:
Kwoth
2021-11-03 14:22:51 +00:00
parent 65062306c6
commit d090aa23ee
21 changed files with 649 additions and 590 deletions

View File

@@ -0,0 +1,8 @@
namespace NadekoBot.Modules.Gambling
{
public enum GamblingError
{
None,
NotEnough
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.Linq;
using NadekoBot.Common;
namespace NadekoBot.Modules.Gambling.Common.Slot
{
public class SlotGame
{
public class Result
{
public float Multiplier { get; }
public int[] Rolls { get; }
public Result(float multiplier, int[] rolls)
{
Multiplier = multiplier;
Rolls = rolls;
}
}
private static readonly Random _rng = new NadekoRandom();
public SlotGame()
{
}
public Result Spin()
{
var rolls = new int[] { _rng.Next(0, 6), _rng.Next(0, 6), _rng.Next(0, 6) };
var multi = 0;
if (rolls.All(x => x == 5))
multi = 30;
else if (rolls.All(x => x == rolls[0]))
multi = 10;
else if (rolls.Count(x => x == 5) == 2)
multi = 4;
else if (rolls.Any(x => x == 5))
multi = 1;
return new Result(multi, rolls);
}
}
}

View File

@@ -0,0 +1,12 @@
using System.Collections.Generic;
namespace NadekoBot.Modules.Gambling
{
public class SlotResponse
{
public float Multiplier { get; set; }
public long Won { get; set; }
public List<int> Rolls { get; set; } = new List<int>();
public GamblingError Error { get; set; }
}
}

View File

@@ -22,15 +22,12 @@ namespace NadekoBot.Modules.Gambling
{
private readonly IImageCache _images;
private readonly ICurrencyService _cs;
private readonly DbService _db;
private static readonly NadekoRandom rng = new NadekoRandom();
public FlipCoinCommands(IDataCache data, ICurrencyService cs, DbService db,
GamblingConfigService gss) : base(gss)
public FlipCoinCommands(IDataCache data, ICurrencyService cs, GamblingConfigService gss) : base(gss)
{
_images = data.LocalImages;
_cs = cs;
_db = db;
}
[NadekoCommand, Aliases]

View File

@@ -6,12 +6,14 @@ using NadekoBot.Modules.Gambling.Common.WheelOfFortune;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using NadekoBot.Common;
using NadekoBot.Db;
using NadekoBot.Modules.Gambling.Common.Slot;
using NadekoBot.Modules.Gambling.Services;
using Serilog;
@@ -82,6 +84,41 @@ WHERE CurrencyAmount > {config.Decay.MinThreshold} AND UserId!={_client.CurrentU
}, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
}
}
public async Task<SlotResponse> SlotAsync(ulong userId, long amount)
{
var takeRes = await _cs.RemoveAsync(userId, "Slot Machine", amount, true);
if (!takeRes)
{
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 * amount);
await _cs.AddAsync(userId, $"Slot Machine x{result.Multiplier}", won, true);
}
var toReturn = new SlotResponse
{
Multiplier = result.Multiplier,
Won = won,
};
toReturn.Rolls.AddRange(result.Rolls);
return toReturn;
}
public struct EconomyResult
{

View File

@@ -9,12 +9,16 @@ using System.Threading;
using System.Threading.Tasks;
using NadekoBot.Common;
using NadekoBot.Common.Attributes;
using NadekoBot.Db.Models;
using NadekoBot.Modules.Gambling.Services;
using NadekoBot.Modules.Gambling.Common;
using NadekoBot.Services;
using SixLabors.Fonts;
using Image = SixLabors.ImageSharp.Image;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
namespace NadekoBot.Modules.Gambling
{
@@ -33,12 +37,16 @@ namespace NadekoBot.Modules.Gambling
//thanks to judge for helping me with this
private readonly IImageCache _images;
private readonly ICurrencyService _cs;
private FontProvider _fonts;
private readonly DbService _db;
public SlotCommands(IDataCache data, ICurrencyService cs, GamblingConfigService gamb) : base(gamb)
public SlotCommands(IDataCache data,
FontProvider fonts, DbService db,
GamblingConfigService gamb) : base(gamb)
{
_images = data.LocalImages;
_cs = cs;
_fonts = fonts;
_db = db;
}
public sealed class SlotMachine
@@ -140,92 +148,115 @@ namespace NadekoBot.Modules.Gambling
[NadekoCommand, Aliases]
public async Task Slot(ShmartNumber amount)
{
if (!_runningUsers.Add(ctx.User.Id))
if (!_runningUsers.Add(ctx.User.Id))
return;
try
{
if (!await CheckBetMandatory(amount).ConfigureAwait(false))
return;
const int maxAmount = 9999;
if (amount > maxAmount)
{
await ReplyErrorLocalizedAsync(strs.max_bet_limit(maxAmount + CurrencySign));
return;
}
try
{
if (!await CheckBetMandatory(amount).ConfigureAwait(false))
return;
await ctx.Channel.TriggerTypingAsync().ConfigureAwait(false);
if (!await _cs.RemoveAsync(ctx.User, "Slot Machine", amount, false, gamble: true).ConfigureAwait(false))
{
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
return;
}
Interlocked.Add(ref _totalBet, amount.Value);
using (var bgImage = Image.Load(_images.SlotBackground))
{
var result = SlotMachine.Pull();
int[] numbers = result.Numbers;
var result = await _service.SlotAsync(ctx.User.Id, amount);
for (int i = 0; i < 3; i++)
{
using (var randomImage = Image.Load(_images.SlotEmojis[numbers[i]]))
{
bgImage.Mutate(x => x.DrawImage(randomImage, new Point(95 + 142 * i, 330), new GraphicsOptions()));
}
}
if (result.Error != GamblingError.None)
{
if (result.Error == GamblingError.NotEnough)
{
await ReplyErrorLocalizedAsync(strs.not_enough(CurrencySign));
}
var won = amount * result.Multiplier;
var printWon = won;
var n = 0;
do
{
var digit = (int)(printWon % 10);
using (var img = Image.Load(_images.SlotNumbers[digit]))
{
bgImage.Mutate(x => x.DrawImage(img, new Point(230 - n * 16, 462), new GraphicsOptions()));
}
n++;
} while ((printWon /= 10) != 0);
return;
}
var printAmount = amount;
n = 0;
do
{
var digit = (int)(printAmount % 10);
using (var img = Image.Load(_images.SlotNumbers[digit]))
{
bgImage.Mutate(x => x.DrawImage(img, new Point(395 - n * 16, 462), new GraphicsOptions()));
}
n++;
} while ((printAmount /= 10) != 0);
Interlocked.Add(ref _totalBet, amount);
Interlocked.Add(ref _totalPaidOut, result.Won);
var msg = GetText(strs.better_luck);
if (result.Multiplier != 0)
{
await _cs.AddAsync(ctx.User, $"Slot Machine x{result.Multiplier}", amount * result.Multiplier, false, gamble: true).ConfigureAwait(false);
Interlocked.Add(ref _totalPaidOut, amount * result.Multiplier);
if (result.Multiplier == 1)
msg = GetText(strs.slot_single(CurrencySign, 1));
else if (result.Multiplier == 4)
msg = GetText(strs.slot_two(CurrencySign, 4));
else if (result.Multiplier == 10)
msg = GetText(strs.slot_three(10));
else if (result.Multiplier == 30)
msg = GetText(strs.slot_jackpot(30));
}
long ownedAmount;
using (var uow = _db.GetDbContext())
{
ownedAmount = uow.Set<DiscordUser>()
.FirstOrDefault(x => x.UserId == ctx.User.Id)
?.CurrencyAmount ?? 0;
}
using (var imgStream = bgImage.ToStream())
{
await ctx.Channel.SendFileAsync(imgStream, "result.png", ctx.User.Mention + " " + msg + $"\n`{GetText(strs.slot_bet)}:`{amount} `{GetText(strs.won)}:` {amount * result.Multiplier}{CurrencySign}").ConfigureAwait(false);
}
}
}
finally
{
var _ = Task.Run(async () =>
{
await Task.Delay(1000).ConfigureAwait(false);
_runningUsers.Remove(ctx.User.Id);
});
}
using (var bgImage = Image.Load<Rgba32>(_images.SlotBackground, out var format))
{
var numbers = new int[3];
result.Rolls.CopyTo(numbers, 0);
bgImage.Mutate(x => x.DrawText(new TextGraphicsOptions
{
TextOptions = new TextOptions()
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
WrapTextWidth = 140,
}
}, result.Won.ToString(), _fonts.DottyFont.CreateFont(65), SixLabors.ImageSharp.Color.Red,
new PointF(227, 92)));
bgImage.Mutate(x => x.DrawText(new TextGraphicsOptions
{
TextOptions = new TextOptions()
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
WrapTextWidth = 135,
}
}, amount.ToString(), _fonts.DottyFont.CreateFont(50), SixLabors.ImageSharp.Color.Red,
new PointF(129, 472)));
bgImage.Mutate(x => x.DrawText(new TextGraphicsOptions
{
TextOptions = new TextOptions()
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
WrapTextWidth = 135,
}
}, ownedAmount.ToString(), _fonts.DottyFont.CreateFont(50), SixLabors.ImageSharp.Color.Red,
new PointF(325, 472)));
//sw.PrintLap("drew red text");
for (var i = 0; i < 3; i++)
{
using (var img = Image.Load(_images.SlotEmojis[numbers[i]]))
{
bgImage.Mutate(x => x.DrawImage(img, new Point(148 + 105 * i, 217), 1f));
}
}
var msg = GetText(strs.better_luck);
if (result.Multiplier > 0)
{
if (result.Multiplier == 1f)
msg = GetText(strs.slot_single(CurrencySign, 1));
else if (result.Multiplier == 4f)
msg = GetText(strs.slot_two(CurrencySign, 4));
else if (result.Multiplier == 10f)
msg = GetText(strs.slot_three(10));
else if (result.Multiplier == 30f)
msg = GetText(strs.slot_jackpot(30));
}
using (var imgStream = bgImage.ToStream())
{
await ctx.Channel.SendFileAsync(imgStream,
filename: "result.png",
text: Format.Bold(ctx.User.ToString()) + " " + msg).ConfigureAwait(false);
}
}
}
finally
{
var _ = Task.Run(async () =>
{
await Task.Delay(1000).ConfigureAwait(false);
_runningUsers.Remove(ctx.User.Id);
});
}
}
}
}