module Degenz.Store open System open System.Threading.Tasks open DSharpPlus.Entities open DSharpPlus open DSharpPlus.EventArgs open DSharpPlus.SlashCommands open Degenz open Degenz.Embeds open Degenz.Shared open Newtonsoft.Json let getItemFromArmoury id = armoury |> Array.find (fun w -> w.Id = id) let removeExpiredActions actions = actions |> Array.filter (fun (act : Action) -> let item = armoury |> Array.find (fun w -> w.Id = act.ActionId) DateTime.UtcNow - act.Timestamp < TimeSpan.FromMinutes(int item.Cooldown)) let viewStore (ctx : InteractionContext) = async { do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, Embeds.storeListing armoury) |> Async.AwaitTask } |> Async.StartAsTask :> Task let buyItem (ctx : InteractionContext) itemId = async { let! playerResult = DbService.tryFindPlayer ctx.Member.Id let item = armoury |> Array.find (fun w -> w.Id = itemId) match playerResult with | Some player -> let newBalance = player.Bank - item.Cost if newBalance >= 0 then let playerHasItem = player.Arsenal |> Array.exists (fun w -> item.Id = w.Id) if not playerHasItem then let p = { player with Bank = newBalance ; Arsenal = Array.append [| item |] player.Arsenal } do! DbService.updatePlayer p do! createSimpleResponseAsync $"Successfully purchased {item.Name}! You now have {newBalance} remaining" ctx else do! createSimpleResponseAsync $"You already own this item!" ctx else do! createSimpleResponseAsync $"You do not have sufficient funds to buy this item! Current balance: {player.Bank} GBT" ctx | None -> do! notYetAHackerMsg ctx } |> Async.StartAsTask :> Task let constructItemButtons playerInfo itemType (items : 'a array) = items |> Seq.map (fun item -> DiscordButtonComponent(ButtonStyle.Primary, $"{playerInfo}-{itemType}-{item}", $"{item}")) let sell (ctx : InteractionContext) = async { let! playerResult = DbService.tryFindPlayer ctx.Member.Id match playerResult with | Some player -> let hasInventoryToSell = Array.length player.Arsenal > 0 if hasInventoryToSell then let builder = DiscordInteractionResponseBuilder() builder.AddEmbed (constructEmbed "Pick the item you wish to sell.") |> ignore Array.chunkBySize 5 player.Arsenal |> Array.iter (fun wps -> wps |> Array.map (fun w -> DiscordButtonComponent(ButtonStyle.Primary, $"{w.Type}-{w.Id}", $"{w.Name}")) |> Seq.cast |> builder.AddComponents |> ignore) builder.AsEphemeral true |> ignore do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask else do! createSimpleResponseAsync "You currently have no inventory to sell" ctx | None -> do! notYetAHackerMsg ctx return () } |> Async.StartAsTask :> Task let updateArsenal player salePrice updatedArsenal = { player with Bank = player.Bank + salePrice ; Arsenal = updatedArsenal } let sellItem (event : ComponentInteractionCreateEventArgs) player itemId = async { let item = armoury |> Array.find (fun i -> i.Id = itemId) let updatedPlayer = { player with Bank = player.Bank + item.Cost ; Arsenal = player.Arsenal |> Array.filter (fun w -> w.Id = itemId)} do! DbService.updatePlayer updatedPlayer let builder = DiscordInteractionResponseBuilder() builder.IsEphemeral <- true builder.Content <- $"Sold {item.Type} {item.Name} for {item.Cost}! Current Balance: {updatedPlayer.Bank}" do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder) |> Async.AwaitTask } let handleSellButtonEvents (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) = async { let! playerResult = DbService.tryFindPlayer event.User.Id match playerResult with | Some player -> let itemId = int <| event.Id.Split("-").[1] do! sellItem event player itemId | None -> let builder = DiscordInteractionResponseBuilder() builder.IsEphemeral <- true builder.Content <- "An error occurred and the user doesn't not exist" do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder) |> Async.AwaitTask } |> Async.StartAsTask :> Task type Store() = inherit ApplicationCommandModule () [] member _.ViewStore (ctx : InteractionContext) = viewStore ctx [] member _.BuyHack (ctx : InteractionContext, [] hackId : HackId) = buyItem ctx (int hackId) [] member this.BuyShield (ctx : InteractionContext, [] shieldId : ShieldId) = buyItem ctx (int shieldId) [] member this.SellItem (ctx : InteractionContext) = sell ctx