130 lines
5.6 KiB
Forth

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<GBT> 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<DiscordComponent>
|> 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 ()
[<SlashCommand("view-store", "View items available for purchase")>]
member _.ViewStore (ctx : InteractionContext) = viewStore ctx
[<SlashCommand("buy-hack", "Purchase a hack attack you can use to earn GoodBoyTokenz")>]
member _.BuyHack (ctx : InteractionContext, [<Option("hack-id", "The ID of the hack you wish to purchase")>] hackId : HackId) =
buyItem ctx (int hackId)
[<SlashCommand("buy-shield", "Purchase a hack shield so you can protect your GoodBoyTokenz")>]
member this.BuyShield (ctx : InteractionContext, [<Option("shield-id", "The ID of the shield you wish to purchase")>] shieldId : ShieldId) =
buyItem ctx (int shieldId)
[<SlashCommand("sell", "Sell an item in your inventory for GoodBoyTokenz")>]
member this.SellItem (ctx : InteractionContext) = sell ctx