From 128726d5a9371c94b88d98f5ce93f5d72ed5f597 Mon Sep 17 00:00:00 2001 From: alogindtractor <251821224+A-Log-In-D-Tractor@users.noreply.github.com> Date: Tue, 13 Jan 2026 18:56:48 -0800 Subject: [PATCH] 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. --- .../Commands/Kasino/SlotsCommand.cs | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/KfChatDotNetBot/Commands/Kasino/SlotsCommand.cs b/KfChatDotNetBot/Commands/Kasino/SlotsCommand.cs index 5811922..e6909de 100644 --- a/KfChatDotNetBot/Commands/Kasino/SlotsCommand.cs +++ b/KfChatDotNetBot/Commands/Kasino/SlotsCommand.cs @@ -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 AnimatedImage { get; set; } + public Image 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); } }