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;
double delayHSec = 0;
using (var board = new KiwiSlotBoard(wager))
{
board.LoadAssets();
@@ -110,25 +111,35 @@ public class SlotsCommand : ICommand
}
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 =
await SettingsProvider.GetMultipleValuesAsync([
BuiltIn.Keys.KiwiFarmsGreenColor, BuiltIn.Keys.KiwiFarmsRedColor
]);
decimal newBalance;
string spinText = spins == 1 ? "" : $" from {spins} spins worth {await wager.FormatKasinoCurrencyAsync()}";
if (winnings == 0) //dud spin(s)
{
newBalance = await Money.NewWagerAsync(gambler.Id, wager*spins, -wager*spins, WagerGame.Slots, ct: ctx);
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));
return;
}
decimal rawWinnings = winnings;
winnings -= wager*spins;
newBalance = await Money.NewWagerAsync(gambler.Id, wager*spins, winnings, WagerGame.Slots, ct: ctx);
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
{
@@ -145,7 +156,7 @@ public class SlotsCommand : ICommand
private Font? _font;
// Optimized Animation Container
private Image<Rgba32> AnimatedImage { get; set; }
public Image<Rgba32> AnimatedImage { get; set; }
private readonly char[,] _preboard = 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;
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()
{
if (AnimatedImage.Frames.Count <= 1) return null;
@@ -339,6 +360,7 @@ public class SlotsCommand : ICommand
ProcessReelsAndWins();
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);
}
}