From 7e2b46a96bab656b767d17ce73d00f7a5e38b14c Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sun, 13 Feb 2022 17:39:12 +0700 Subject: [PATCH] Stealing mechanic with different scenarios and maths, start RPS game --- Bot/Bot.fsproj | 5 +-- Bot/GuildEnvironment.fs | 1 + Bot/RockPaperScissors.fs | 53 +++++++++++++++++++++++++++ Bot/Thief.fs | 77 ++++++++++++++++++++++++++++++++-------- 4 files changed, 119 insertions(+), 17 deletions(-) create mode 100644 Bot/RockPaperScissors.fs diff --git a/Bot/Bot.fsproj b/Bot/Bot.fsproj index 66e530b..cb720fe 100644 --- a/Bot/Bot.fsproj +++ b/Bot/Bot.fsproj @@ -15,9 +15,10 @@ - - + + + diff --git a/Bot/GuildEnvironment.fs b/Bot/GuildEnvironment.fs index 06bc84a..a7e5eb7 100644 --- a/Bot/GuildEnvironment.fs +++ b/Bot/GuildEnvironment.fs @@ -22,6 +22,7 @@ let channelBattle = getId "CHANNEL_BATTLE" let botIdHackerBattle = getId "BOT_HACKER_BATTLE" let botIdArmory = getId "BOT_ARMORY" let roleTrainee = getId "ROLE_TRAINEE" +let rolePrisoner = getId "ROLE_PRISONER" let mutable botUserHackerBattle : DiscordUser option = None let mutable botUserArmory : DiscordUser option = None diff --git a/Bot/RockPaperScissors.fs b/Bot/RockPaperScissors.fs new file mode 100644 index 0000000..2203e9b --- /dev/null +++ b/Bot/RockPaperScissors.fs @@ -0,0 +1,53 @@ +module Degenz.RockPaperScissors + +open System +open System.Threading.Tasks +open DSharpPlus +open DSharpPlus.Entities +open DSharpPlus.SlashCommands +open Degenz.Messaging + +type Move = + | Rock + | Paper + | Scissor + +type RoundResult = + | P1Win + | P2Win + | Draw + +let player1Won p1m p2m = + match p1m , p2m with + | Rock , Paper -> P2Win + | Rock , Scissor -> P1Win + | Paper , Rock -> P1Win + | Paper , Scissor -> P2Win + | Scissor , Rock -> P2Win + | Scissor , Paper -> P1Win + | _ , _ -> Draw + +let playRPS target ctx = + Game.executePlayerWithTargetAction target ctx (fun attacker defender -> async { + + return () + }) + +type StealGame() = + inherit ApplicationCommandModule () + + let enforceChannel (ctx : IDiscordContext) (storeFn : IDiscordContext -> Task) = + match ctx.GetChannel().Id with + | id when id = GuildEnvironment.channelArmory -> storeFn ctx + | _ -> + task { + let msg = $"You must go to <#{GuildEnvironment.channelArmory}> channel to buy or sell weapons" + do! Messaging.sendSimpleResponse ctx msg + } + + [] + member this.RPS (ctx : InteractionContext, [] target : DiscordUser) = +// enforceChannel (DiscordInteractionContext ctx) (steal target) + playRPS target (DiscordInteractionContext ctx) + + diff --git a/Bot/Thief.fs b/Bot/Thief.fs index 84a90a7..2382013 100644 --- a/Bot/Thief.fs +++ b/Bot/Thief.fs @@ -7,6 +7,11 @@ open DSharpPlus.Entities open DSharpPlus.SlashCommands open Degenz.Messaging +type StealResult = + | Success + | WentToPrison + | TargetRanAway + let getRandomStealBtnLabels () = let rand = Random(Guid.NewGuid().GetHashCode()) let affirmative = [| "LFG" ; "YOLO" ; "IDGAF" |] @@ -20,22 +25,28 @@ let chanceOfSuccessMsg = function | _ -> "Totally worth it" let targetEvaluationMsg = function - | amt when amt < 0.20 -> "but man, they look swole." + | amt when amt < 0.20 -> "but man, they look swole" | amt when amt < 0.50 -> "but they look a little confident" | amt when amt < 0.80 -> "and they're looking a little nervous" | _ -> "and they look weak af man" -let payoutChance targetBank chance = targetBank * 0.1 * (1.0 - chance) +let payout defenderBank chance = + let rand = Random(Guid.NewGuid().GetHashCode()) + let baseAmount = defenderBank * 0.1 * (1.0 - chance) + let randomBonus = baseAmount * rand.NextDouble() * chance |> ceil + let randomAmount = baseAmount + randomBonus |> int + max 1 randomAmount -let getStealEmbed chance (target : PlayerData) (player : PlayerData) = +let getStealEmbed chance prize (target : PlayerData) = let buttons = let yes , no = getRandomStealBtnLabels () - [ DiscordButtonComponent(ButtonStyle.Success, $"Steal-yes-{target.DiscordId}-{target.Name}-{chance}", yes) + [ DiscordButtonComponent(ButtonStyle.Success, $"Steal-yes-{target.DiscordId}-{target.Name}-{chance}-{prize}", yes) DiscordButtonComponent(ButtonStyle.Danger, $"Steal-no", no) ] |> Seq.cast let embed = DiscordEmbedBuilder() .AddField("Chance of Success", $"{chanceOfSuccessMsg chance}", true) + .AddField("Payout", $"{prize}", true) .WithDescription($"{target.Name} is coming towards you in a dark alley, {targetEvaluationMsg chance}") .WithImageUrl("https://cdnb.artstation.com/p/assets/images/images/017/553/457/large/maarten-hof-backalley-mainshot.jpg") .WithTitle($"Steal Money") @@ -45,11 +56,34 @@ let getStealEmbed chance (target : PlayerData) (player : PlayerData) = .AddComponents(buttons) .AsEphemeral(true) +let getResultEmbed targetName result = + let resultMsg , msg , img = + match result with + | Success -> + "You successfully robbed the poor bastard" + , "Your mean ugly face and athletic physique intimidated your poor victim into giving you their money" + , "https://f8n-production-collection-assets.imgix.net/0x3B3ee1931Dc30C1957379FAc9aba94D1C48a5405/127502/QmPLPg1CLovKzS7mP8QkrMoHws1D4VZTzpfbZBALLwKZ5b/nft.png" + | WentToPrison -> + "Looks like you went to prison" + , $"{targetName} knows Karate and elbowed you in the nose. While unconscious, they called the cops. You're on your way to prison now... " + , "https://thumbs.dreamstime.com/b/vector-pixel-art-prisoner-isolated-cartoon-vector-pixel-art-prisoner-129807237.jpg" + | TargetRanAway -> + "You tried to snatch their money and they ran away" + , $"{targetName} got nervous seeing a shadowy figure and ran in the opposite direction" + , "https://i.imgur.com/NLHMvVK.jpg" + + DiscordEmbedBuilder() + .AddField("Result" , resultMsg) + .WithDescription(msg) + .WithImageUrl(img) + .WithTitle($"Robbery Results") let steal target (ctx : IDiscordContext) = Game.executePlayerWithTargetAction target ctx (fun attacker defender -> async { - let winPercentage = if attacker.Stats.Strength > defender.Stats.Strength then 1.0 else 0.0 - let embed = getStealEmbed winPercentage defender attacker + let ``base`` = 0.5 + let winPercentage = double (attacker.Stats.Strength - defender.Stats.Strength) * 0.45 + ``base`` + let prize = payout (float defender.Bank) winPercentage + let embed = getStealEmbed winPercentage prize defender do! ctx.FollowUp(embed) |> Async.AwaitTask }) @@ -62,17 +96,31 @@ let handleSteal (ctx : IDiscordContext) = let targetId = uint64 split.[2] let targetName = split.[3] let chance = double split.[4] + let prize = int split.[5] * 1 let rand = Random(Guid.NewGuid().GetHashCode()) - let result = rand.NextDouble() - if chance >= result then - let! target = DbService.tryFindPlayer targetId - do! Messaging.sendFollowUpMessage ctx $"You stole {targetName} money" - else - do! Messaging.sendFollowUpMessage ctx "You failed miserably" - - return () + let result = chance >= rand.NextDouble() , rand.Next(0,3) = 0 + match result with + | true , _ -> + let xp = 15 + let embed = getResultEmbed targetName Success + embed.AddField("$GBT Stolen", string prize) |> ignore + embed.AddField("XP Gained", $"{xp}+") |> ignore + do! Messaging.sendFollowUpEmbed ctx (embed.Build()) + match! DbService.tryFindPlayer targetId with + | Some t -> do! DbService.updatePlayer { t with Bank = max (t.Bank - prize) 0 } + | None -> () + do! DbService.updatePlayer { player with Bank = player.Bank + prize ; XP = player.XP + xp } + | false , false -> + let embed = getResultEmbed targetName TargetRanAway + do! Messaging.sendFollowUpEmbed ctx (embed.Build()) + | false , true -> + let embed = getResultEmbed targetName WentToPrison + do! Messaging.sendFollowUpEmbed ctx (embed.Build()) + do! Async.Sleep 5000 + let role = ctx.GetGuild().GetRole(GuildEnvironment.rolePrisoner) + do! ctx.GetDiscordMember().GrantRoleAsync(role) |> Async.AwaitTask }) else async { @@ -81,7 +129,6 @@ let handleSteal (ctx : IDiscordContext) = do! ctx.Respond InteractionResponseType.UpdateMessage builder |> Async.AwaitTask } |> Async.StartAsTask :> Task - type StealGame() = inherit ApplicationCommandModule ()