namespace Degenz open System.Threading.Tasks open DSharpPlus open DSharpPlus.Entities open DSharpPlus.EventArgs open DSharpPlus.SlashCommands open Degenz.DbService module Game = let HackPrize = 10 let ShieldPrize = 5 let SameTargetAttackCooldown = System.TimeSpan.FromHours(6) let getClassButtonColor = function | Network -> ButtonStyle.Danger | Exploit -> ButtonStyle.Success | Penetration -> ButtonStyle.Primary let getClassEmbedColor = function | Network -> DiscordColor.Red | Penetration -> DiscordColor.Blurple | Exploit -> DiscordColor.Green let executePlayerInteraction (ctx : InteractionContext) (dispatch : PlayerData -> Async) = async { let builder = DiscordInteractionResponseBuilder() builder.IsEphemeral <- true builder.Content <- "Content" do! ctx.CreateResponseAsync(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask let! playerResult = tryFindPlayer ctx.Member.Id match playerResult with | Some player -> do! dispatch player | None -> do! Messaging.sendFollowUpMessageFromCtx ctx "You are currently not a hacker, first use the /redpill command to become one" } |> Async.StartAsTask :> Task // TODO J: Create an abstraction for these two helper functions let executePlayerEvent (event : ComponentInteractionCreateEventArgs) (dispatch : PlayerData -> Async) = async { let builder = DiscordInteractionResponseBuilder() builder.IsEphemeral <- true builder.Content <- "Content" do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask let! playerResult = tryFindPlayer event.User.Id match playerResult with | Some player -> do! dispatch player | None -> do! Messaging.sendInteractionEvent event "You are currently not a hacker, first use the /redpill command to become one" } |> Async.StartAsTask :> Task module Player = let hacks (player : PlayerData) = player.Arsenal |> Array.filter (fun bi -> bi.Type = Hack) let shields (player : PlayerData) = player.Arsenal |> Array.filter (fun bi -> bi.Type = Shield) let attacks player = player.Actions |> Array.filter (fun act -> match act.Type with Attack _ -> true | _ -> false) let defenses player = player.Actions |> Array.filter (fun act -> match act.Type with Defense -> true | _ -> false) let removeExpiredActions player = let actions = player.Actions |> Array.filter (fun (act : Action) -> match act.Type with // So the player doesnt attack the same player so many times in a row | Attack _ -> System.DateTime.UtcNow - act.Timestamp < Game.SameTargetAttackCooldown | Defense -> let item = Armory.getItem act.ActionId System.DateTime.UtcNow - act.Timestamp < System.TimeSpan.FromMinutes(int item.Cooldown)) { player with Actions = actions } let modifyBank (player : PlayerData) amount = { player with Bank = max (player.Bank + amount) 0 } let getAttacksFlat actions = actions |> Array.choose (fun act -> match act.Type with Attack ar -> Some (act,ar.Target,ar.Result) | Defense -> None)