discord-bot-game/Bot/PlayerInteractions.fs

109 lines
4.8 KiB
Forth

module Degenz.PlayerInteractions
open System.Threading.Tasks
open DSharpPlus
open DSharpPlus.Entities
open DSharpPlus.SlashCommands
open Degenz.Messaging
open Degenz.DbService
let executePlayerAction (ctx : IDiscordContext) (dispatch : PlayerData -> Async<unit>) =
async {
let builder = DiscordInteractionResponseBuilder().AsEphemeral(true)
do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask
let! playerResult = tryFindPlayer GuildEnvironment.pgDb (ctx.GetDiscordMember().Id)
match playerResult with
| Some player -> do! dispatch player
| None -> do! Messaging.sendFollowUpMessage ctx "You are currently not a hacker, first use the /redpill command to become one"
} |> Async.StartAsTask :> Task
let executePlayerActionWithTarget (targetPlayer : DiscordUser) (ctx : IDiscordContext) (dispatch : PlayerData -> PlayerData -> Async<unit>) =
async {
let builder = DiscordInteractionResponseBuilder()
builder.IsEphemeral <- true
builder.Content <- "Content"
do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask
let! players =
[ tryFindPlayer GuildEnvironment.pgDb (ctx.GetDiscordMember().Id)
tryFindPlayer GuildEnvironment.pgDb targetPlayer.Id ]
|> Async.Parallel
match players.[0] , players.[1] with
| Some player , Some target -> do! dispatch player target
| None , _ -> do! Messaging.sendFollowUpMessage ctx "You are currently not a hacker, first use the /redpill command to become one"
| _ , None ->
if targetPlayer.IsBot
then do! Messaging.sendFollowUpMessage ctx $"{targetPlayer.Username} is a bot, pick a real human to hack"
else do! Messaging.sendFollowUpMessage ctx "Your target is not connected to the network, they must join first by using the /redpill command"
} |> Async.StartAsTask :> Task
let executePlayerActionWithTargetId defer (targetId : uint64) (ctx : IDiscordContext) (dispatch : PlayerData -> PlayerData -> Async<unit>) =
async {
let builder = DiscordInteractionResponseBuilder()
builder.IsEphemeral <- true
builder.Content <- "Content"
if defer then
do! ctx.Respond(InteractionResponseType.DeferredChannelMessageWithSource, builder) |> Async.AwaitTask
let! players =
[ tryFindPlayer GuildEnvironment.pgDb (ctx.GetDiscordMember().Id)
tryFindPlayer GuildEnvironment.pgDb targetId ]
|> Async.Parallel
match players.[0] , players.[1] with
| Some player , Some target -> do! dispatch player target
| None , _ -> do! Messaging.sendFollowUpMessage ctx "You are currently not a hacker, first use the /redpill command to become one"
| _ , None -> do! Messaging.sendFollowUpMessage ctx "Your target is not connected to the network, they must join first by using the /redpill command"
} |> Async.StartAsTask :> Task
let handleResultWithResponse ctx fn (player : Result<PlayerData, string>) =
match player with
| Ok p -> fn p
| Error e -> async { do! Messaging.sendFollowUpMessage ctx e }
module Commands =
let newPlayer nickname (membr : uint64) =
let rand = System.Random(System.Guid.NewGuid().GetHashCode())
let randHack = rand.Next(0, 3)
let randShield = rand.Next(6, 9)
let hack = Armory.battleItems |> Array.find (fun i -> i.Id = randHack)
let shield = Armory.battleItems |> Array.find (fun i -> i.Id = randShield)
{ DiscordId = membr
Name = nickname
Inventory = [| hack ; shield |]
Events = [||]
// XP = 0
// Achievements = [||]
Traits = PlayerTraits.empty
Bank = 100<GBT> }
let upsertPlayer discordId =
async {
let! player = DbService.tryFindPlayer GuildEnvironment.pgDb discordId
let! newPlayer =
match player with
| Some _ -> async.Return false
| None ->
async {
// do! newPlayer "" discordId |> DbService.insertNewPlayer
return true
}
return newPlayer
}
[<CLIMutable>]
type LeaderboardEntry = {
Position : string
Amount : string
Name : string
}
type PlayerInteractions() =
inherit ApplicationCommandModule ()
[<SlashCommand("redpill", "Take the redpill and become a hacker")>]
member _.AddHackerRole (ctx : InteractionContext) = Commands.upsertPlayer ctx.Member.Id
// [<SlashCommand("leaderboard", "View the current list of players ranked by highest earnings")>]
// member this.Leaderboard (ctx : InteractionContext) = Commands.leaderboard ctx