adds pause between spins and delays win/lose message based on length of image (#45)

* adds delay based on frame count so it doesn't spoil outcome on long spins

adds delay based on frame count so it doesn't spoil outcome on long spins

* adds pause between each spin

adds pause between each spin

* Refactor delay calculation for slot animation

Replaced delaySec with delayHSec to calculate delay based on frame delays.
This commit is contained in:
alogindtractor
2026-01-13 18:56:48 -08:00
committed by GitHub
parent cf45a14eff
commit 128726d5a9

View File

@@ -94,6 +94,7 @@ public class SlotsCommand : ICommand
} }
decimal winnings; decimal winnings;
double delayHSec = 0;
using (var board = new KiwiSlotBoard(wager)) using (var board = new KiwiSlotBoard(wager))
{ {
board.LoadAssets(); board.LoadAssets();
@@ -110,25 +111,35 @@ public class SlotsCommand : ICommand
} }
winnings = (decimal)board.RunningTotalDisplay; winnings = (decimal)board.RunningTotalDisplay;
// We skip index 0 if it's the blank placeholder frame
for (int i = 1; i < board.AnimatedImage.Frames.Count; i++)
{
delayHSec += board.AnimatedImage.Frames[i].Metadata.GetWebpMetadata().FrameDelay;
}
} }
await Task.Delay(TimeSpan.FromSeconds(delayHSec));//adds delay to stop message showing gambling win/loss too early based on total frame count of the animated image
var colors = var colors =
await SettingsProvider.GetMultipleValuesAsync([ await SettingsProvider.GetMultipleValuesAsync([
BuiltIn.Keys.KiwiFarmsGreenColor, BuiltIn.Keys.KiwiFarmsRedColor BuiltIn.Keys.KiwiFarmsGreenColor, BuiltIn.Keys.KiwiFarmsRedColor
]); ]);
decimal newBalance; decimal newBalance;
string spinText = spins == 1 ? "" : $" from {spins} spins worth {await wager.FormatKasinoCurrencyAsync()}";
if (winnings == 0) //dud spin(s) if (winnings == 0) //dud spin(s)
{ {
newBalance = await Money.NewWagerAsync(gambler.Id, wager*spins, -wager*spins, WagerGame.Slots, ct: ctx); newBalance = await Money.NewWagerAsync(gambler.Id, wager*spins, -wager*spins, WagerGame.Slots, ct: ctx);
await botInstance.SendChatMessageAsync( await botInstance.SendChatMessageAsync(
$"{user.FormatUsername()} you [color={colors[BuiltIn.Keys.KiwiFarmsRedColor].Value}]lost[/color]. Current balance: {await newBalance.FormatKasinoCurrencyAsync()}", $"{user.FormatUsername()} you [color={colors[BuiltIn.Keys.KiwiFarmsRedColor].Value}]lost[/color] {await (wager*spins).FormatKasinoCurrencyAsync()}{spins}. Current balance: {await newBalance.FormatKasinoCurrencyAsync()}",
true, autoDeleteAfter: TimeSpan.FromSeconds(30)); true, autoDeleteAfter: TimeSpan.FromSeconds(30));
return; return;
} }
decimal rawWinnings = winnings;
winnings -= wager*spins; winnings -= wager*spins;
newBalance = await Money.NewWagerAsync(gambler.Id, wager*spins, winnings, WagerGame.Slots, ct: ctx); newBalance = await Money.NewWagerAsync(gambler.Id, wager*spins, winnings, WagerGame.Slots, ct: ctx);
await botInstance.SendChatMessageAsync( await botInstance.SendChatMessageAsync(
$"{user.FormatUsername()}, you [color={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]won[/color] {await winnings.FormatKasinoCurrencyAsync()}! Current balance: {await newBalance.FormatKasinoCurrencyAsync()}", true, autoDeleteAfter: TimeSpan.FromSeconds(30)); $"{user.FormatUsername()}, you [color={colors[BuiltIn.Keys.KiwiFarmsGreenColor].Value}]won[/color] {rawWinnings.FormatKasinoCurrencyAsync()}{spins}! Current balance: {await newBalance.FormatKasinoCurrencyAsync()}", true, autoDeleteAfter: TimeSpan.FromSeconds(30));
} }
public class WinDetail public class WinDetail
{ {
@@ -145,7 +156,7 @@ public class SlotsCommand : ICommand
private Font? _font; private Font? _font;
// Optimized Animation Container // Optimized Animation Container
private Image<Rgba32> AnimatedImage { get; set; } public Image<Rgba32> AnimatedImage { get; set; }
private readonly char[,] _preboard = new char[5, 5]; private readonly char[,] _preboard = new char[5, 5];
private char[,] _board = new char[5, 5]; private char[,] _board = new char[5, 5];
@@ -299,7 +310,17 @@ public class SlotsCommand : ICommand
frame.Frames.RootFrame.Metadata.GetWebpMetadata().FrameDelay = 2; frame.Frames.RootFrame.Metadata.GetWebpMetadata().FrameDelay = 2;
AnimatedImage.Frames.AddFrame(frame.Frames.RootFrame); AnimatedImage.Frames.AddFrame(frame.Frames.RootFrame);
} }
private void AddPause(int hundredthsOfASecond)
{
// Render the current state as a static frame
RenderFrame();
// Modify the delay of the very last frame we just added
var lastFrame = AnimatedImage.Frames[^1];
lastFrame.Metadata.GetWebpMetadata().FrameDelay = (ushort)hundredthsOfASecond;
}
public MemoryStream? ExportAndCleanup() public MemoryStream? ExportAndCleanup()
{ {
if (AnimatedImage.Frames.Count <= 1) return null; if (AnimatedImage.Frames.Count <= 1) return null;
@@ -339,6 +360,7 @@ public class SlotsCommand : ICommand
ProcessReelsAndWins(); ProcessReelsAndWins();
var total = _activeFeatureTier switch { 3 => 3, 4 => 5, 5 => 10, _ => 0 }; var total = _activeFeatureTier switch { 3 => 3, 4 => 5, 5 => 10, _ => 0 };
if (total > 0 || featureSpins != 0 || spins > 1) AddPause(50);
if (featureSpins == 0) for (var s = 1; s <= total; s++) ExecuteGameLoop(1,s); if (featureSpins == 0) for (var s = 1; s <= total; s++) ExecuteGameLoop(1,s);
} }
} }