module Degenz.SlotMachine open System open System.IO open System.Threading.Tasks open DSharpPlus open DSharpPlus.Entities open DSharpPlus.EventArgs open Degenz.Messaging open Degenz.Types type SlotSymbol = { index : int reel1Count : int reel2Count : int reel3Count : int } let BigBrother = { index = 0 ; reel1Count = 1 ; reel2Count = 1 ; reel3Count = 1 } let Eye = { index = 1 ; reel1Count = 3 ; reel2Count = 2 ; reel3Count = 1 } let Obey = { index = 2 ; reel1Count = 2 ; reel2Count = 2 ; reel3Count = 2 } let AnonMask = { index = 3 ; reel1Count = 1 ; reel2Count = 5 ; reel3Count = 8 } let Ramen = { index = 5 ; reel1Count = 5 ; reel2Count = 5 ; reel3Count = 4 } let Sushi = { index = 4 ; reel1Count = 7 ; reel2Count = 3 ; reel3Count = 3 } let Pizza = { index = 6 ; reel1Count = 2 ; reel2Count = 6 ; reel3Count = 0 } let Alcohol = { index = 7 ; reel1Count = 1 ; reel2Count = 1 ; reel3Count = 1 } //let Circuit = { index = 0 ; reel1Count = 0 ; reel2Count = 0 ; reel3Count = 4 } //let OldTv = { index = 9 ; reel1Count = 1 ; reel2Count = 1 ; reel3Count = 1 } //let Pills = { index = 10 ; reel1Count = 1 ; reel2Count = 1 ; reel3Count = 1 } //let Rat = { index = 11 ; reel1Count = 1 ; reel2Count = 1 ; reel3Count = 1 } //let symbols = [ BigBrother ; Eye ; Obey ; AnonMask ; Sushi ; Ramen ; Pizza ; Alcohol ; Circuit ; OldTv ; Pills ; Rat ] let symbols = [ BigBrother ; Eye ; Obey ; AnonMask ; Sushi ; Ramen ; Pizza ; Alcohol ] let getReel fn = List.fold (fun acc elem -> List.replicate (fn elem) elem.index @ acc) [] symbols |> List.toArray let reel1 = getReel (fun s -> s.reel1Count) let reel2 = getReel (fun s -> s.reel2Count) let reel3 = getReel (fun s -> s.reel3Count) type Prize = | Money of int | Jackpot type Slot = | Symbol of SlotSymbol | Any let prizeTable = [ Symbol BigBrother , Symbol BigBrother , Symbol BigBrother , Jackpot Symbol Eye , Symbol Eye , Symbol Eye , Money 1000 Symbol Eye , Symbol Eye , Symbol Obey , Money 1000 Symbol AnonMask , Symbol AnonMask , Symbol AnonMask , Money 250 Symbol AnonMask , Symbol AnonMask , Symbol Eye , Money 250 Symbol Ramen , Symbol Ramen , Symbol Ramen , Money 100 Symbol Ramen , Symbol Ramen , Symbol Eye , Money 100 Symbol Sushi , Symbol Sushi , Any , Money 10 Symbol Pizza , Any , Any , Money 5 ] let slots = [| "https://s7.gifyu.com/images/aneye.png" "https://s7.gifyu.com/images/anonmask.png" "https://s7.gifyu.com/images/circuitboard.png" "https://s7.gifyu.com/images/obey.png" "https://s7.gifyu.com/images/oldtv.png" "https://s7.gifyu.com/images/pills.png" "https://s7.gifyu.com/images/pizza0d47578733961746.png" "https://s7.gifyu.com/images/ramen0515f00869e1f4eb.png" "https://s7.gifyu.com/images/rat69609f842a0eb9f5.png" "https://s7.gifyu.com/images/alcohol.png" "https://s7.gifyu.com/images/bigbrother.png" "https://s7.gifyu.com/images/sushi.png" |] // [| "https://s7.gifyu.com/images/A-bottle-of-pills0a3006d0170e08df.png" // "https://s7.gifyu.com/images/an-eyec362d8152ae2382b.png" // "https://s7.gifyu.com/images/anon-face-mask6c7624821c89fc08.png" // "https://s7.gifyu.com/images/a-piece-of-sushi77071d30f60a89c6.png" // "https://s7.gifyu.com/images/Circuit-board89056017b80f1d13.png" // "https://s7.gifyu.com/images/OBEYf2a8234109836c03.png" // "https://s7.gifyu.com/images/old-tv-screendc6bc9d4b6c1fd65.png" // "https://s7.gifyu.com/images/pizza030ffc00ff50da0e.png" // "https://s7.gifyu.com/images/ramen08336d448018c98f.png" // "https://s7.gifyu.com/images/rat14f65f54f0d75036.png" |] let slotEmojis = [| "<:sushi:>" "<:pizza:>" "<:ramen:>" "<:circuitboard:>" "<:obey:>" "<:pills:>" "<:oldtv:>" "<:rat:>" "<:aneye:>" "<:anon:>" |] let slotsImages = [| "./images/anonmask.png" "./images/circuitboard.png" "./images/aneye.png" "./images/obey.png" "./images/oldtv.png" "./images/pills.png" "./images/pizza.png" "./images/ramen.png" "./images/rat.png" "./images/bigbrother.png" "./images/alcohol.png" "./images/sushi.png" |] // |> Array.map (fun path -> ( Path.GetFileNameWithoutExtension(path) , File.OpenRead(path) )) let payTable = [| |] let PlayPrice = 10 let twoOfAKindPrize = 100 let threeOfAKindPrize = 1000 let sleepTime = 1500 let spinEmbeds (results : int array) (ctx : IDiscordContext) = async { let itx = ctx.GetInteraction() let builder = DiscordFollowupMessageBuilder() builder.Content <- "Spinning!" builder.IsEphemeral <- true let e1 = DiscordEmbedBuilder().WithImageUrl(slots.[results[0]]) let e2 = DiscordEmbedBuilder().WithImageUrl(slots.[results[1]]) let e3 = DiscordEmbedBuilder().WithImageUrl(slots.[results[2]]) let! followUp = itx.CreateFollowupMessageAsync(builder) |> Async.AwaitTask do! Async.Sleep sleepTime let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().AddEmbeds([ e1.Build() ])) |> Async.AwaitTask do! Async.Sleep sleepTime let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().AddEmbeds([ e1.Build() ; e2.Build() ])) |> Async.AwaitTask do! Async.Sleep sleepTime let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().AddEmbeds([ e1.Build() ; e2.Build() ; e3.Build() ])) |> Async.AwaitTask do! Async.Sleep sleepTime let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().AddEmbeds([ e1.Build() ; e2.Build() ; e3.Build() ])) |> Async.AwaitTask return () } let spinEmojis (results : int array) (ctx : IDiscordContext) = async { let itx = ctx.GetInteraction() let emojis = ctx.GetGuild().Emojis |> Seq.map (fun kvp -> kvp.Value) |> Seq.toArray let builder = DiscordFollowupMessageBuilder() builder.Content <- "Spinning!" builder.IsEphemeral <- true let! followUp = itx.CreateFollowupMessageAsync(builder) |> Async.AwaitTask do! Async.Sleep sleepTime let content = $"{Formatter.Emoji(emojis.[results.[0]])}" let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().WithContent(content)) |> Async.AwaitTask do! Async.Sleep sleepTime let content = $"{Formatter.Emoji(emojis.[results.[0]])}{Formatter.Emoji(emojis.[results.[1]])}" let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().WithContent(content)) |> Async.AwaitTask do! Async.Sleep sleepTime let content = $"{Formatter.Emoji(emojis.[results.[0]])}{Formatter.Emoji(emojis.[results.[1]])}{Formatter.Emoji(emojis.[results.[2]])}" let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder().WithContent(content)) |> Async.AwaitTask return () } let spinFiles (results : int array) (ctx : IDiscordContext) = async { let itx = ctx.GetInteraction() let builder = DiscordFollowupMessageBuilder() builder.Content <- "Spinning!" builder.IsEphemeral <- true let! followUp = itx.CreateFollowupMessageAsync(builder) |> Async.AwaitTask do! Async.Sleep sleepTime // let ( name , stream ) = slotsImages.[results.[0]] // let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder() // .AddFile(name + "1.png", stream)) |> Async.AwaitTask // do! Async.Sleep sleepTime // let ( name , stream ) = slotsImages.[results.[1]] // let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder() // .AddFile(name + "2.png", stream)) |> Async.AwaitTask // do! Async.Sleep sleepTime // let ( name , stream ) = slotsImages.[results.[2]] // let! _ = itx.EditFollowupMessageAsync(followUp.Id, DiscordWebhookBuilder() // .AddFile(name + "3.png", stream)) |> Async.AwaitTask return () } let spin spinType (ctx : IDiscordContext) = PlayerInteractions.executePlayerAction ctx (fun player -> async { let random = Random(Guid.NewGuid().GetHashCode()) let symbols = [| reel1.[random.Next(0, reel1.Length)] ; reel2.[random.Next(0, reel2.Length)] ; reel3.[random.Next(0, reel3.Length)] |] let winConditions = symbols.[0] = symbols.[1] && symbols.[0] = symbols.[2] let prize = prizeTable |> List.pick (fun (s1,s2,s3,prize) -> match s1 , s2 , s3 with | Symbol s1' , Symbol s2' , Symbol s3' when s1'.index = symbols.[0] && s2'.index = symbols.[1] && s3'.index = symbols.[2] -> Some prize | Symbol s1' , Symbol s2' , Any when s1'.index = symbols.[0] && s2'.index = symbols.[1] -> Some prize | Symbol s1' , Any , Any when s1'.index = symbols.[0] -> Some prize | _ -> None) if winConditions then do! DbService.updatePlayerCurrency twoOfAKindPrize player |> Async.Ignore else do! DbService.updatePlayerCurrency -PlayPrice player |> Async.Ignore match spinType with | "Embeds" -> do! spinEmbeds symbols ctx | "Emojis" -> do! spinEmojis symbols ctx | "Files" -> do! spinFiles symbols ctx | _ -> () do! Async.Sleep sleepTime let builder = DiscordFollowupMessageBuilder() builder.IsEphemeral <- true let embed4 = DiscordEmbedBuilder() embed4.Title <- "Slot Machine" if winConditions then embed4.Description <- $"You win {threeOfAKindPrize} GBT!" else builder.Content <- "Better luck next time! You paid 1 $GBT" builder.AddEmbed(embed4) |> ignore do! ctx.FollowUp(builder) |> Async.AwaitTask |> Async.Ignore return () }) let handleSpin (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) = let ctx = DiscordEventContext event task { match event.Id with | "spin-embeds" -> do! spin "Embeds" ctx | "spin-emojis" -> do! spin "Emojis" ctx | "spin-files" -> do! spin "Files" ctx | _ -> printfn "Wrong Spin ID" return () } :> Task let sendInitialEmbed (ctx : IDiscordContext) = async { try let channel = ctx.GetGuild().GetChannel(GuildEnvironment.channelSlots) let builder = DiscordMessageBuilder() let embed = DiscordEmbedBuilder() embed.Title <- "Degenz Slot Machine" embed.Description <- "Hello I am an embed" embed.ImageUrl <- "https://i.kym-cdn.com/photos/images/original/001/169/608/a43.gif" builder.AddEmbed(embed) |> ignore let button1 = DiscordButtonComponent(ButtonStyle.Success, $"spin-embeds", $"Spin Embeds 1 $GBT") :> DiscordComponent let button2 = DiscordButtonComponent(ButtonStyle.Success, $"spin-emojis", $"Spin Emojis 5 $GBT") :> DiscordComponent let button3 = DiscordButtonComponent(ButtonStyle.Success, $"spin-files", $"Spin Files 10 $GBT") :> DiscordComponent builder.AddComponents [| button1 ; button2 ; button3 |] |> ignore do! GuildEnvironment.botClientSlots.Value.SendMessageAsync(channel, builder) |> Async.AwaitTask |> Async.Ignore with e -> printfn $"Error trying to get channel Training Dojo\n\n{e.Message}" } |> Async.RunSynchronously