added prices to .nczoom

.nc resized to 250x125
This commit is contained in:
Toastie 2025-03-30 15:38:40 +13:00
parent 57a5993064
commit c058d180ae
Signed by: toastie_t0ast
GPG key ID: 0861BE54AD481DC7
5 changed files with 101 additions and 49 deletions
src/EllieBot
Modules/Games/NCanvas
_common/Services/Impl
data
strings

View file

@ -35,17 +35,22 @@ public partial class Games
public async Task NCanvas() public async Task NCanvas()
{ {
var pixels = await _service.GetCanvas(); var pixels = await _service.GetCanvas();
var image = new Image<Rgba32>(_service.GetWidth(), _service.GetHeight()); var w = _service.GetWidth();
var h = _service.GetHeight();
var image = new Image<Rgba32>(w * 2, h * 2);
Parallel.For(0, Parallel.For(0,
image.Height, h * 2,
y => y =>
{ {
var pixelAccessor = image.DangerousGetPixelRowMemory(y); var pixelAccessor = image.DangerousGetPixelRowMemory(y);
var row = pixelAccessor.Span; var row = pixelAccessor.Span;
for (int x = 0; x < image.Width; x++) for (var x = 0; x < image.Width; x += 2)
{ {
row[x] = new Rgba32(pixels[(y * image.Width) + x]); var pi = pixels[(y / 2 * w) + x / 2];
row[x] = new Rgba32(pi);
row[x + 1] = new Rgba32(pi);
} }
}); });
@ -53,15 +58,15 @@ public partial class Games
var hint = GetText(strs.nc_hint(prefix, _service.GetWidth(), _service.GetHeight())); var hint = GetText(strs.nc_hint(prefix, _service.GetWidth(), _service.GetHeight()));
await Response() await Response()
.File(stream, "ncanvas.png") .File(stream, "ncanvas.png")
.Embed(CreateEmbed() .Embed(CreateEmbed()
.WithOkColor() .WithOkColor()
#if GLOBAL_ELLIE #if GLOBAL_ELLIE
.WithDescription("This is not available yet.") .WithDescription("This is not available yet.")
#endif #endif
.WithFooter(hint) .WithFooter(hint)
.WithImageUrl("attachment://ncanvas.png")) .WithImageUrl("attachment://ncanvas.png"))
.SendAsync(); .SendAsync();
} }
[Cmd] [Cmd]
@ -85,8 +90,8 @@ public partial class Games
var eb = CreateEmbed() var eb = CreateEmbed()
.WithOkColor() .WithOkColor()
.WithImageUrl($"attachment://zoom_{position}.png") .WithImageUrl($"attachment://zoom_{position}.png")
.WithFooter($"`.ncs code color` to set. (.ncs abc green)" ); .WithFooter($"`.ncs code color` to set. (.ncs abc green)");
await Response() await Response()
.Embed(eb) .Embed(eb)
.File(stream, $"zoom_{position}.png") .File(stream, $"zoom_{position}.png")
@ -106,11 +111,13 @@ public partial class Games
const float fontSize = 30; const float fontSize = 30;
var posFont = _fonts.NotoSans.CreateFont(fontSize, FontStyle.Bold); var posFont = _fonts.NotoSans.CreateFont(fontSize, FontStyle.Bold);
var priceFont = _fonts.Symbola.CreateFont(25, FontStyle.Bold);
var size = TextMeasurer.MeasureSize("wwww", new TextOptions(posFont)); var size = TextMeasurer.MeasureSize("wwww", new TextOptions(posFont));
var scale = 100f / size.Width; var scale = 100f / size.Width;
if (scale < 1) if (scale < 1)
posFont = _fonts.NotoSans.CreateFont(fontSize * scale, FontStyle.Bold); posFont = _fonts.NotoSans.CreateFont(fontSize * scale, FontStyle.Bold);
var outlinePen = new SolidPen(SixLabors.ImageSharp.Color.Black, 1f); var outlinePen = new SolidPen(SixLabors.ImageSharp.Color.Black, 0.5f);
Parallel.For(0, Parallel.For(0,
pixels.Length, pixels.Length,
@ -128,14 +135,26 @@ public partial class Games
image.Mutate(x => image.Mutate(x =>
{ {
x.DrawText(new RichTextOptions(posFont) x.DrawText(new RichTextOptions(posFont)
{ {
HorizontalAlignment = HorizontalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center, VerticalAlignment = VerticalAlignment.Center,
Origin = new(startX + 50, startY + 50) Origin = new(startX + 50, startY + 30)
}, },
((kwum)pix.Position).ToString().PadLeft(2, '2'), ((kwum)pix.Position).ToString().PadLeft(2, '2'),
Brushes.Solid(SixLabors.ImageSharp.Color.White), Brushes.Solid(SixLabors.ImageSharp.Color.White),
outlinePen); outlinePen);
x.DrawText(new RichTextOptions(priceFont)
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Origin = new(startX + 50, startY + 80)
},
// "", Brushes.Solid(SixLabors.ImageSharp.Color.White), outlinePen);
pix.Price + "💵",
// CurrencyHelper.N(pix.Price, Culture, _gcs.Data.Currency.Sign),
Brushes.Solid(SixLabors.ImageSharp.Color.White),
outlinePen);
}); });
}); });
@ -165,8 +184,8 @@ public partial class Games
_gcs.Data.Currency.Sign)))); _gcs.Data.Currency.Sign))));
if (!await PromptUserConfirmAsync(CreateEmbed() if (!await PromptUserConfirmAsync(CreateEmbed()
.WithPendingColor() .WithPendingColor()
.WithDescription(prompt))) .WithDescription(prompt)))
{ {
return; return;
} }
@ -193,12 +212,12 @@ public partial class Games
await using var stream = await img.ToStreamAsync(); await using var stream = await img.ToStreamAsync();
await Response() await Response()
.Embed(CreateEmbed() .Embed(CreateEmbed()
.WithOkColor() .WithOkColor()
.WithDescription(GetText(strs.nc_pixel_set(Format.Code(position.ToString())))) .WithDescription(GetText(strs.nc_pixel_set(Format.Code(position.ToString()))))
.WithImageUrl($"attachment://zoom_{position}.png")) .WithImageUrl($"attachment://zoom_{position}.png"))
.File(stream, $"zoom_{position}.png") .File(stream, $"zoom_{position}.png")
.SendAsync(); .SendAsync();
} }
[Cmd] [Cmd]
@ -230,18 +249,18 @@ public partial class Games
var pos = new kwum(pixel.Position); var pos = new kwum(pixel.Position);
await Response() await Response()
.File(stream, $"{pixel.Position}.png") .File(stream, $"{pixel.Position}.png")
.Embed(CreateEmbed() .Embed(CreateEmbed()
.WithOkColor() .WithOkColor()
.WithDescription(string.IsNullOrWhiteSpace(pixel.Text) ? string.Empty : pixel.Text) .WithDescription(string.IsNullOrWhiteSpace(pixel.Text) ? string.Empty : pixel.Text)
.WithTitle(GetText(strs.nc_pixel(pos))) .WithTitle(GetText(strs.nc_pixel(pos)))
.AddField(GetText(strs.nc_position), .AddField(GetText(strs.nc_position),
$"{pixel.Position % _service.GetWidth()} {pixel.Position / _service.GetWidth()}", $"{pixel.Position % _service.GetWidth()} {pixel.Position / _service.GetWidth()}",
true) true)
.AddField(GetText(strs.price), pixel.Price.ToString(), true) .AddField(GetText(strs.price), pixel.Price.ToString(), true)
.AddField(GetText(strs.color), "#" + new Rgba32(pixel.Color).ToHex()) .AddField(GetText(strs.color), "#" + new Rgba32(pixel.Color).ToHex())
.WithImageUrl($"attachment://{pixel.Position}.png")) .WithImageUrl($"attachment://{pixel.Position}.png"))
.SendAsync(); .SendAsync();
} }
[Cmd] [Cmd]
@ -264,9 +283,9 @@ public partial class Games
} }
if (!await PromptUserConfirmAsync(CreateEmbed() if (!await PromptUserConfirmAsync(CreateEmbed()
.WithDescription( .WithDescription(
"This will reset the canvas to the specified image. All prices, text and colors will be reset.\n\n" "This will reset the canvas to the specified image. All prices, text and colors will be reset.\n\n"
+ "Are you sure you want to continue?"))) + "Are you sure you want to continue?")))
return; return;
using var http = _http.CreateClient(); using var http = _http.CreateClient();
@ -294,9 +313,9 @@ public partial class Games
await _service.ResetAsync(); await _service.ResetAsync();
if (!await PromptUserConfirmAsync(CreateEmbed() if (!await PromptUserConfirmAsync(CreateEmbed()
.WithDescription( .WithDescription(
"This will delete all pixels and reset the canvas.\n\n" "This will delete all pixels and reset the canvas.\n\n"
+ "Are you sure you want to continue?"))) + "Are you sure you want to continue?")))
return; return;
await ctx.OkAsync(); await ctx.OkAsync();

View file

@ -20,8 +20,8 @@ public sealed class NCanvasService : INCanvasService, IReadyExecutor, IEService
private readonly ICurrencyService _cs; private readonly ICurrencyService _cs;
private readonly QuestService _quests; private readonly QuestService _quests;
public const int CANVAS_WIDTH = 500; public const int CANVAS_WIDTH = 250;
public const int CANVAS_HEIGHT = 350; public const int CANVAS_HEIGHT = 125;
public const int INITIAL_PRICE = 3; public const int INITIAL_PRICE = 3;
public NCanvasService( public NCanvasService(
@ -45,8 +45,35 @@ public sealed class NCanvasService : INCanvasService, IReadyExecutor, IEService
await using var uow = _db.GetDbContext(); await using var uow = _db.GetDbContext();
if (await uow.GetTable<NCPixel>().CountAsyncLinqToDB() > 0) var count = await uow.GetTable<NCPixel>().CountAsync();
if (count == CANVAS_WIDTH * CANVAS_HEIGHT)
return; return;
var oldWidth = 500;
var oldHeight = 250;
if (count == oldWidth * oldHeight)
{
await uow.GetTable<NCPixel>()
.Where(x => x.Position % (oldWidth * 2) % 2 != 0 // x is odd
|| (x.Position / oldWidth) % 2 != 0) // or y is odd
.DeleteAsync();
await uow.GetTable<NCPixel>()
.Where(x => x.Position % (oldWidth * 2) % 2 == 0
&& (x.Position / oldWidth) % 2 == 0)
.UpdateAsync(old => new()
{
Position = (old.Position % oldWidth) / 2
+ ((old.Position / oldWidth) / 2) * CANVAS_WIDTH,
Price = INITIAL_PRICE,
Text = old.Text,
OwnerId = old.OwnerId,
Color = old.Color,
});
return;
}
await ResetAsync(); await ResetAsync();
} }

View file

@ -6,6 +6,7 @@ namespace EllieBot.Services;
public class FontProvider : IEService public class FontProvider : IEService
{ {
public FontFamily NotoSans { get; } public FontFamily NotoSans { get; }
public FontFamily Symbola { get; }
public List<FontFamily> FallBackFonts { get; } public List<FontFamily> FallBackFonts { get; }
private readonly FontCollection _fonts; private readonly FontCollection _fonts;
@ -14,6 +15,7 @@ public class FontProvider : IEService
_fonts = new(); _fonts = new();
NotoSans = _fonts.Add("data/fonts/NotoSans-Bold.ttf"); NotoSans = _fonts.Add("data/fonts/NotoSans-Bold.ttf");
Symbola = _fonts.Add("data/fonts/Symbola-10.24.ttf");
FallBackFonts = new(); FallBackFonts = new();
@ -27,7 +29,9 @@ public class FontProvider : IEService
FallBackFonts.AddRange(_fonts.AddCollection(Path.Combine(fontsfolder, "msgothic.ttc"))); FallBackFonts.AddRange(_fonts.AddCollection(Path.Combine(fontsfolder, "msgothic.ttc")));
FallBackFonts.AddRange(_fonts.AddCollection(Path.Combine(fontsfolder, "segoe.ttc"))); FallBackFonts.AddRange(_fonts.AddCollection(Path.Combine(fontsfolder, "segoe.ttc")));
} }
catch { } catch
{
}
} }
// any fonts present in data/fonts should be added as fallback fonts // any fonts present in data/fonts should be added as fallback fonts

View file

@ -4315,7 +4315,8 @@
"Aliases": [ "Aliases": [
".ncsetpixel", ".ncsetpixel",
".ncsp", ".ncsp",
".ncs" ".ncs",
".ncset"
], ],
"Description": "Sets a pixel's color and text on the nCanvas.\nYou must specify the position of the pixel to set in alphanumeric format.\nYou can obtain alphanumeric position of the pixel by using `nczoom` or `ncp <x> <y>`", "Description": "Sets a pixel's color and text on the nCanvas.\nYou must specify the position of the pixel to set in alphanumeric format.\nYou can obtain alphanumeric position of the pixel by using `nczoom` or `ncp <x> <y>`",
"Usage": [ "Usage": [

View file

@ -1484,6 +1484,7 @@ ncsetpixel:
- ncsetpixel - ncsetpixel
- ncsp - ncsp
- ncs - ncs
- ncset
nczoom: nczoom:
- nczoom - nczoom
- ncz - ncz