diff --git a/Bot/Bot.fs b/Bot/Bot.fs index 8efcaf0..6982c29 100644 --- a/Bot/Bot.fs +++ b/Bot/Bot.fs @@ -74,7 +74,7 @@ let run (client : DiscordClient) = do! client.ConnectAsync () |> Async.AwaitTask } -//Trainer.sendInitialEmbed hackerBattleBot +Trainer.sendInitialEmbed hackerBattleBot clients |> Array.map run diff --git a/Bot/Embeds.fs b/Bot/Embeds.fs index abbc6ee..9acf8b1 100644 --- a/Bot/Embeds.fs +++ b/Bot/Embeds.fs @@ -73,12 +73,12 @@ let responseSuccessfulHack defenderName hack prize = .AddEmbed(embed.Build()) .AsEphemeral(true) -let responseSuccessfulHackTrainer defenderName (hack : BattleItem) prize = +let responseSuccessfulHackTrainer (hack : BattleItem) = let embed = DiscordEmbedBuilder() embed.ImageUrl <- getHackGif (enum(hack.Id)) DiscordFollowupMessageBuilder() - .WithContent($"Successfully hacked {defenderName} using {hack.Name}! You just won {prize} GoodBoyTokenz!") + .WithContent($"You successfully hacked <@{GuildEnvironment.botHackerBattle}> using {hack.Name}, and stole 💰$GBT {Game.HackPrize} from them!") .AddEmbed(embed.Build()) .AsEphemeral(true) diff --git a/Bot/Game.fs b/Bot/Game.fs index 76ea0b9..42f142d 100644 --- a/Bot/Game.fs +++ b/Bot/Game.fs @@ -1,10 +1,14 @@ module Degenz.Game open System.Threading.Tasks +open DSharpPlus.EventArgs open DSharpPlus.SlashCommands open Degenz.DbService -let executePlayerAction (ctx : InteractionContext) (dispatch : PlayerData -> Async) = +let HackPrize = 10 +let ShieldPrize = 5 + +let executePlayerInteraction (ctx : InteractionContext) (dispatch : PlayerData -> Async) = async { let! playerResult = tryFindPlayer ctx.Member.Id match playerResult with @@ -13,3 +17,13 @@ let executePlayerAction (ctx : InteractionContext) (dispatch : PlayerData -> Asy } |> Async.StartAsTask :> Task +// TODO: Create an abstraction for these two helper functions +let executePlayerEvent (ctx : ComponentInteractionCreateEventArgs) (dispatch : PlayerData -> Async) = + async { + let! playerResult = tryFindPlayer ctx.User.Id + match playerResult with + | Some player -> do! dispatch player + | None -> do! Messaging.sendInteractionEvent ctx "You are currently not a hacker, first use the /redpill command to become one" + } |> Async.StartAsTask + :> Task + diff --git a/Bot/GuildEnvironment.fs b/Bot/GuildEnvironment.fs index 08bab28..94c7091 100644 --- a/Bot/GuildEnvironment.fs +++ b/Bot/GuildEnvironment.fs @@ -16,5 +16,7 @@ let tokenHackerBattle = getVar "TOKEN_HACKER_BATTLE" let tokenStore = getVar "TOKEN_STORE" let channelEventsHackerBattle = getId "CHANNEL_EVENTS_HACKER_BATTLE" let channelTraining = getId "CHANNEL_TRAINING" +let channelArmory = getId "CHANNEL_ARMORY" let botHackerBattle = getId "BOT_HACKER_BATTLE" +let botArmory = getId "BOT_ARMORY" let roleTrainee = getId "ROLE_TRAINEE" diff --git a/Bot/HackerBattle.fs b/Bot/HackerBattle.fs index 0c27523..ea2305d 100644 --- a/Bot/HackerBattle.fs +++ b/Bot/HackerBattle.fs @@ -46,12 +46,12 @@ let checkIfHackHasCooldown hackId attacker = Ok attacker else let cooldown = getTimeTillCooldownFinishes (TimeSpan.FromMinutes(5)) mostRecentHackAttack - let item = Armoury.battleItems |> Array.find (fun i -> i.Id = hackId) + let item = Armory.battleItems |> Array.find (fun i -> i.Id = hackId) Error $"{item.Name} is currently on cooldown, wait {cooldown} to use it again." let checkIfInventoryIsEmpty attacker = match attacker.Arsenal with - | [||] -> Error $"You currently do not have any Hacks to use against others. Please go to the store and purchase one." + | [||] -> Error $"You currently do not have any Hacks to steal 💰$GBT from others. Please go to the <#{GuildEnvironment.channelArmory}> and purchase one." | _ -> Ok attacker let calculateDamage (hack : BattleItem) (shield : BattleItem) = @@ -62,7 +62,7 @@ let calculateDamage (hack : BattleItem) (shield : BattleItem) = let runHackerBattle defender hack = Player.defenses defender |> Player.removeExpiredActions - |> Array.map (fun dfn -> Armoury.battleItems |> Array.find (fun w -> w.Id = dfn.ActionId)) + |> Array.map (fun dfn -> Armory.battleItems |> Array.find (fun w -> w.Id = dfn.ActionId)) |> Array.map (calculateDamage (hack)) |> Array.contains Weak @@ -79,15 +79,13 @@ let updateCombatants attacker defender hack prize = let successfulHack (event : ComponentInteractionCreateEventArgs) attacker defender hack = async { - let prize = 3 + do! updateCombatants attacker defender hack Game.HackPrize - do! updateCombatants attacker defender hack prize - - let embed = Embeds.responseSuccessfulHack defender.Name hack prize + let embed = Embeds.responseSuccessfulHack defender.Name hack Game.HackPrize do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed) |> Async.AwaitTask - let builder = Embeds.eventSuccessfulHack event defender.DiscordId prize + let builder = Embeds.eventSuccessfulHack event defender.DiscordId Game.HackPrize let channel = event.Guild.GetChannel(GuildEnvironment.channelEventsHackerBattle) do! channel.SendMessageAsync(builder) |> Async.AwaitTask @@ -97,16 +95,15 @@ let successfulHack (event : ComponentInteractionCreateEventArgs) attacker defend let failedHack (event : ComponentInteractionCreateEventArgs) attacker defender hack = async { let builder = DiscordInteractionResponseBuilder() - let prize = 2 builder.IsEphemeral <- true - builder.Content <- $"Hack failed! {defender.Name} was able to mount a successful defense! You lost {prize} GoodBoyTokenz!" + builder.Content <- $"Hack failed! {defender.Name} was able to mount a successful defense! You lost {Game.ShieldPrize} GoodBoyTokenz!" do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask - do! updateCombatants attacker defender hack -prize + do! updateCombatants attacker defender hack -Game.ShieldPrize let builder = DiscordMessageBuilder() - builder.WithContent($"Hacking attempt failed! <@{defender.DiscordId}> defended hack from {event.User.Username} and took {prize} from them! ") |> ignore + builder.WithContent($"Hacking attempt failed! <@{defender.DiscordId}> defended hack from {event.User.Username} and took {Game.ShieldPrize} from them! ") |> ignore let channel = (event.Guild.GetChannel(GuildEnvironment.channelEventsHackerBattle)) do! channel.SendMessageAsync(builder) |> Async.AwaitTask @@ -114,7 +111,7 @@ let failedHack (event : ComponentInteractionCreateEventArgs) attacker defender h } let attack (ctx : InteractionContext) (target : DiscordUser) = - Game.executePlayerAction ctx (fun attacker -> async { + Game.executePlayerInteraction ctx (fun attacker -> async { let! defender = DbService.tryFindPlayer target.Id match defender with | Some defender -> @@ -151,7 +148,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) = |> Result.bind (checkIfHackHasCooldown (int hack)) |> function | Ok _ -> - runHackerBattle defender (Armoury.getItem (int hack)) + runHackerBattle defender (Armory.getItem (int hack)) |> function | false -> successfulHack event attacker defender hack | true -> failedHack event attacker defender hack @@ -171,14 +168,14 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) = } let defend (ctx : InteractionContext) = - Game.executePlayerAction ctx (fun player -> async { + Game.executePlayerInteraction ctx (fun player -> async { if Player.shields player |> Array.length > 0 then let embed = Embeds.pickDefense "Defend" player do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed) |> Async.AwaitTask else let builder = DiscordInteractionResponseBuilder() - builder.Content <- $"You currently do not have any Shields to protect your system. Please go to the armoury and purchase one." + builder.Content <- $"You currently do not have any Shields to protect you. Please go to the <#{GuildEnvironment.channelArmory}> and purchase one." builder.AsEphemeral true |> ignore do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask @@ -263,8 +260,8 @@ type HackerGame() = else attack ctx target - [] - member this.DefendCommand (ctx : InteractionContext) = + [] + member this.ShieldCommand (ctx : InteractionContext) = if ctx.Channel.Id = GuildEnvironment.channelTraining then Trainer.defend ctx else diff --git a/Bot/PlayerInteractions.fs b/Bot/PlayerInteractions.fs index 6592805..a4e4e0a 100644 --- a/Bot/PlayerInteractions.fs +++ b/Bot/PlayerInteractions.fs @@ -12,8 +12,8 @@ module Commands = let rand = System.Random(System.Guid.NewGuid().GetHashCode()) let randHack = rand.Next(0, 3) let randShield = rand.Next(6, 9) - let hack = Armoury.battleItems |> Array.find (fun i -> i.Id = randHack) - let shield = Armoury.battleItems |> Array.find (fun i -> i.Id = randShield) + 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 @@ -72,7 +72,7 @@ module Commands = // :> Task let status (ctx : InteractionContext) = - Game.executePlayerAction ctx (fun player -> async { + Game.executePlayerInteraction ctx (fun player -> async { let updatedActions = Player.removeExpiredActions player.Actions let updatedPlayer = { player with Actions = updatedActions } let builder = DiscordInteractionResponseBuilder() diff --git a/Bot/SlotMachine.fs b/Bot/SlotMachine.fs index a46b4de..b401ed9 100644 --- a/Bot/SlotMachine.fs +++ b/Bot/SlotMachine.fs @@ -14,7 +14,7 @@ type SlotMachine() = [] member this.Spin (ctx : InteractionContext) = - Game.executePlayerAction ctx (fun player -> async { + Game.executePlayerInteraction ctx (fun player -> async { let sleepTime = 1000 let random = Random(System.Guid.NewGuid().GetHashCode()) let results = [ random.Next(0, 3) ; random.Next(0, 3) ; random.Next(0, 3)] diff --git a/Bot/Store.fs b/Bot/Store.fs index 21c2ccf..476038a 100644 --- a/Bot/Store.fs +++ b/Bot/Store.fs @@ -12,13 +12,13 @@ open Degenz.Messaging let viewStore (ctx : InteractionContext) = async { - do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, Embeds.storeListing Armoury.battleItems) + do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, Embeds.storeListing Armory.battleItems) |> Async.AwaitTask } |> Async.StartAsTask :> Task let buyItem (ctx : InteractionContext) itemType = - Game.executePlayerAction ctx (fun player -> async { + Game.executePlayerInteraction ctx (fun player -> async { let embed = DiscordEmbedBuilder() // embed.Fields @@ -28,7 +28,7 @@ let buyItem (ctx : InteractionContext) itemType = }) let sell (ctx : InteractionContext) = - Game.executePlayerAction ctx (fun player -> async { + Game.executePlayerInteraction ctx (fun player -> async { let hasInventoryToSell = Array.length player.Arsenal > 0 if hasInventoryToSell then let builder = DiscordInteractionResponseBuilder() @@ -52,7 +52,7 @@ let sell (ctx : InteractionContext) = let sellItem (event : ComponentInteractionCreateEventArgs) player itemId = async { - let item = Armoury.battleItems |> Array.find (fun i -> i.Id = itemId) + let item = Armory.battleItems |> 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() @@ -63,8 +63,8 @@ let sellItem (event : ComponentInteractionCreateEventArgs) player itemId = } let handleBuyItem (ctx : InteractionContext) itemId = - Game.executePlayerAction ctx (fun player -> async { - let item = Armoury.battleItems |> Array.find (fun w -> w.Id = itemId) + Game.executePlayerInteraction ctx (fun player -> async { + let item = Armory.battleItems |> Array.find (fun w -> w.Id = itemId) let newBalance = player.Bank - item.Cost if newBalance >= 0 then let playerHasItem = player.Arsenal |> Array.exists (fun w -> item.Id = w.Id) diff --git a/Bot/Trainer.fs b/Bot/Trainer.fs index 241e28f..ba06668 100644 --- a/Bot/Trainer.fs +++ b/Bot/Trainer.fs @@ -8,8 +8,8 @@ open DSharpPlus.SlashCommands open Degenz.Types open Degenz.Messaging -let defaultHack = Armoury.battleItems |> Array.find (fun i -> i.Id = int HackId.Virus) -let defaultShield = Armoury.battleItems |> Array.find (fun i -> i.Id = int ShieldId.Firewall) +let defaultHack = Armory.battleItems |> Array.find (fun i -> i.Id = int HackId.Virus) +let defaultShield = Armory.battleItems |> Array.find (fun i -> i.Id = int ShieldId.Encryption) let sendInitialEmbed (client : DiscordClient) = async { @@ -18,145 +18,102 @@ let sendInitialEmbed (client : DiscordClient) = let embed = DiscordEmbedBuilder() embed.ImageUrl <- "https://s10.gifyu.com/images/MasterTraining_Degenz.gif" builder.AddEmbed embed |> ignore - builder.Content <- "Welcome to the hacker dojo you degenerate, are you ready to get started?" - let button = DiscordButtonComponent(ButtonStyle.Success, $"Trainer-1", $"Get started") :> DiscordComponent + builder.Content <- "Welcome Degen… To the Hacker Training Program.\n" + + "Here you will learn how to defend yourself, and hack other Degenz to steal their 💰$GBT.\n" + + "Are you ready?" + let button = DiscordButtonComponent(ButtonStyle.Success, $"Trainer-1", $"LFG") :> DiscordComponent builder.AddComponents [| button |] |> ignore do! channel.SendMessageAsync(builder) |> Async.AwaitTask |> Async.Ignore } |> Async.RunSynchronously -let step1Msg = { - ButtonId = "Trainer-2" - ButtonText = "Show me" - Message = "First time, eh? Beautopia is a dangerous place. I'm going to teach you how to protect yourself from other degenerates. " - + "And in the process, I'll also show you how to hack some sheeple, so you can earn some cash." -} - let handleTrainerStep1 (event : ComponentInteractionCreateEventArgs) = - async { - let! maybePlayer = DbService.tryFindPlayer event.User.Id + Game.executePlayerEvent event (fun player -> async { + let weaponName = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name - do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate) - |> Async.AwaitTask - match maybePlayer with - | Some _ -> - do! sendFollowUpMessageWithButton event step1Msg - | None -> - let msg = "Looks like an error occurred, you're not a registered degenerate. Please contact a moderator." - do! sendFollowUpMessage event msg - } + let shieldMessage = + if Player.shields player |> Array.isEmpty + then $"You do not have any Shields in your arsenal, take this {defaultShield.Name}, you can use it for now" + else $"Looks like you have `{weaponName}` in your arsenal… 👀\n" -let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) = - async { - let! result = DbService.tryFindPlayer event.User.Id - match result with - | Some player -> - let weaponName = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name - do! updateMessageWithGreyedOutButtons event step1Msg - - let shieldMessage = - if Player.shields player |> Array.isEmpty - then $"You do not have any Shields in your arsenal, here's a {defaultShield.Name} you can use for now" - else $"You currently have {weaponName} in your arsenal" - - do! sendFollowUpMessage event - ($"First things first, let's get your system protected. Let's enable a shield to protect you from potential hackers. " - + $"{shieldMessage}. To enable it and protect your system, you can use the `/defend` slash command to choose a shield." - + $"\n\nRun the `/defend` command now and then select '{weaponName}'.") - | None -> - do! sendFollowUpMessage event $"Something went wrong, please contact a moderator" - } + do! sendInteractionEvent event + ("Beautopia© is a dangerous place...\n" + + "Quick, put up a DEFENSE 🛡 before another Degen hacks you, and steals your 💰$GBT.\n" + + shieldMessage + + "To enable it, you need to run the `/shield` slash command.\n\n" + + $"Type the `/shield` command now, then select - `{weaponName}`\n") + }) let defend (ctx : InteractionContext) = - async { - let! playerResult = DbService.tryFindPlayer ctx.Member.Id - match playerResult with - | Some player -> - let playerWithShields = - match player.Arsenal with - | [||] -> { player with Arsenal = [| defaultShield |] } - | _ -> player - let embed = Embeds.pickDefense "Trainer-3" playerWithShields + Game.executePlayerInteraction ctx (fun player -> async { + let playerWithShields = + match player.Arsenal with + | [||] -> { player with Arsenal = [| defaultShield |] } + | _ -> player + let embed = Embeds.pickDefense "Trainer-2" playerWithShields - do! ctx.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed) - |> Async.AwaitTask - | None -> - let builder = DiscordInteractionResponseBuilder() - builder.Content <- "Error, please contact a moderator" - - builder.AsEphemeral true |> ignore - - do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) - |> Async.AwaitTask - } |> Async.StartAsTask - :> Task + do! ctx.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed) + |> Async.AwaitTask + }) let handleDefenseMsg = { - ButtonId = "Trainer-4" + ButtonId = "Trainer-3" ButtonText = "Got it" - Message = "I wasn't able to hack you. Great job! Because you had your system protected when I tried to hack you, you took some money from me. " - + "Shields only protect you for a certain amount of time, so remember to keep your system protected at all times." + Message = "🎉 Congratulations 🎉\n\n" + + "You successfully defended my hack!\n\n" + + "Because I tried hacking you when you had your defense up, you stole money from me...\n" + + "Defenses only protect you for a LIMITED TIME, so remember to keep at least 1 defense up at all times, or risk getting hacked!" } let handleDefense (event : ComponentInteractionCreateEventArgs) = - let sendMessage' = sendFollowUpMessage event - async { + Game.executePlayerEvent event (fun player -> async { + let sendMessage' = sendFollowUpMessage event do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate) |> Async.AwaitTask - let! maybePlayer = DbService.tryFindPlayer event.User.Id - match maybePlayer with - | Some player -> - let prize = 0.223f - let shield = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield - let embed = Embeds.responseCreatedShieldTrainer shield - do! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore - do! Async.Sleep 2000 - do! sendMessage' "Ok, good, let me make sure that worked. I'll try to hack you now" - do! Async.Sleep 4000 - do! sendMessage' $"Hacking attempt failed! {player.Name} defended hack from Degenz-Trainer and took {prize} from them! " - do! Async.Sleep 3000 - do! sendFollowUpMessageWithButton event handleDefenseMsg - | None -> - do! sendMessage' $"Something went wrong, please contact a moderator" - } + let shield = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield + let embed = Embeds.responseCreatedShieldTrainer shield + do! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore + do! Async.Sleep 2000 + do! sendMessage' "Ok, good, let me make sure that worked.\n\nI'll try to **hack** you now" + do! Async.Sleep 4000 + do! sendMessage' $"❌ HACKING FAILED! ❌\n\n{player.Name} defended the hack from <@{GuildEnvironment.botHackerBattle}>, and stole 💰$GBT {Game.ShieldPrize} from them!" + do! Async.Sleep 3000 + do! sendFollowUpMessageWithButton event handleDefenseMsg + }) -let handleTrainerStep4 (event : ComponentInteractionCreateEventArgs) = - async { - let! result = DbService.tryFindPlayer event.User.Id - match result with - | Some player -> - let weaponName = Player.hacks player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name - do! updateMessageWithGreyedOutButtons event handleDefenseMsg +let handleTrainerStep3 (event : ComponentInteractionCreateEventArgs) = + Game.executePlayerEvent event (fun player -> async { + let weaponName = Player.hacks player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name + do! updateMessageWithGreyedOutButtons event handleDefenseMsg - let hackMessage = - if Player.shields player |> Array.isEmpty - then $"You do not have any Hacks in your arsenal, here's a {defaultHack.Name} you can use for now" - else $"You currently have {weaponName} in your arsenal" + let hackMessage = + if Player.shields player |> Array.isEmpty + then $"You do not have any Hacks in your arsenal, take this {defaultHack.Name}, you can use it for now" + else $"Looks like you have `{weaponName}` in your arsenal..." - do! sendFollowUpMessage event - ($"Next why don't you try hacking me. {hackMessage}. To hack me and get some money, " - + $" you can use the '/hack' slash command and select a user to hack, then choose the hack attack you wish to use." - + $"\n\nRun the `/hack` command now and pick me as your target, then click on the '{weaponName}' button.") - | None -> - do! sendInteractionEvent event $"Something went wrong, please contact a moderator" - } + do! sendFollowUpMessage event + ("Now let’s **HACK!** 💻\n\n" + + "I want you to **HACK ME**, and try to steal my 💰$GBT...\n\n" + + hackMessage + + "To deploy it, you need to run the `/hack` slash command.\n" + + $"Type the `/hack` command now, then choose me - <@{GuildEnvironment.botHackerBattle}> as your target, and select - `{weaponName}`") + }) let attack (ctx : InteractionContext) (target : DiscordUser) = - async { + Game.executePlayerInteraction ctx (fun player -> async { let isRightTarget = target.Id = GuildEnvironment.botHackerBattle - let! playerResult = DbService.tryFindPlayer ctx.Member.Id - match isRightTarget , playerResult with - | true , Some player -> + match isRightTarget with + | true -> let playerWithAttacks = match player.Arsenal with | [||] -> { player with Arsenal = [| defaultHack |] } | _ -> player - let embed = Embeds.pickHack "Trainer-5" playerWithAttacks player + let embed = Embeds.pickHack "Trainer-4" playerWithAttacks player do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed) |> Async.AwaitTask - | false , _ -> + | false -> let builder = DiscordInteractionResponseBuilder() builder.Content <- "You picked the wrong target, you dufus. Try again, this time pick me!" @@ -164,72 +121,37 @@ let attack (ctx : InteractionContext) (target : DiscordUser) = do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) |> Async.AwaitTask - | _ -> - let builder = DiscordInteractionResponseBuilder() - builder.Content <- "Error, please contact a moderator" - - builder.AsEphemeral true |> ignore - - do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder) - |> Async.AwaitTask - } |> Async.StartAsTask - :> Task - -let handleAttackMsg = { - ButtonId = "Trainer-6" - ButtonText = "Hell yeah" - Message = "I think we're done. You are going to need more hacks and shields if you want to survive in this crazy world. " - + "Remember to go check out the store and purchase whatever you need to add to your arsenal." - + "\n\nAlright you degenerate, off you go!" -} + }) let handleAttack (event : ComponentInteractionCreateEventArgs) = - let sendMessage' = sendFollowUpMessage event - async { + Game.executePlayerEvent event (fun player -> async { + let sendMessage' = sendFollowUpMessage event do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate) |> Async.AwaitTask - let! result = DbService.tryFindPlayer event.User.Id - match result with - | Some player -> - let prize = 2 - do! Async.Sleep 1000 - let hack = player.Arsenal |> Array.tryHead |> Option.defaultValue defaultHack - let embed = Embeds.responseSuccessfulHackTrainer $"<@{GuildEnvironment.botHackerBattle}>" hack prize - do! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore - do! Async.Sleep 3000 - do! sendMessage' ("Look at that, you are now officially an elite haxor! By successfully hacking other people you can earn GoodBoyTokenz. " - + "Hacks take time to recover so check back in later once you've used all your hacks.") - do! Async.Sleep 7000 - do! sendFollowUpMessageWithButton event handleAttackMsg - | None -> - do! sendMessage' $"Something went wrong, please contact a moderator" - } - -let handleTrainerStep6 (event : ComponentInteractionCreateEventArgs) = - async { -// let! membr = event.Guild.GetMemberAsync(event.User.Id) |> Async.AwaitTask -// let role = event.Guild.GetRole(GuildEnvironment.roleTrainee) -// do! membr.RevokeRoleAsync(role) |> Async.AwaitTask - - let builder = DiscordFollowupMessageBuilder() - builder.IsEphemeral <- true - builder.Content <- "Get out of here!" - do! updateMessageWithGreyedOutButtons event handleAttackMsg - do! event.Interaction.CreateFollowupMessageAsync(builder) - |> Async.AwaitTask - |> Async.Ignore - } + do! Async.Sleep 1000 + let hack = Player.hacks player |> Array.tryHead |> Option.defaultValue defaultHack + let embed = Embeds.responseSuccessfulHackTrainer hack + do! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore + do! Async.Sleep 3000 + do! sendMessage' ("🎉 **Congratulations** 🎉\n\n" + + "You successfully **HACKED** me, and are now an **Elite Haxor!**\n\n" + + "When you **HACK** other Degenz, you **STEAL** their 💰**$GBT.**\n" + + "But remember, hacks take time to recover, so use them wisely.") + do! Async.Sleep 7000 + do! sendFollowUpMessage event ("Your training is **complete!**\n\n" + + "But, you’re going to need more **HACKS & DEFENSES** 🛡 to survive in **Beautopia©...**\n" + + $"You can purchase them from <@{GuildEnvironment.botArmory}>, at <#{GuildEnvironment.channelArmory}> anytime you want...\n\n" + + "Go there **NOW** to buy **HACKS** & **SHIELDS** before you get hacked! 😱") + }) let handleButtonEvent (event : ComponentInteractionCreateEventArgs) = async { let split = event.Id.Split("-") match int split.[1] with - | 1 -> do! handleTrainerStep1 event - | 2 -> do! handleTrainerStep2 event - | 3 -> do! handleDefense event - | 4 -> do! handleTrainerStep4 event - | 5 -> do! handleAttack event - | 6 -> do! handleTrainerStep6 event + | 1 -> do! handleTrainerStep1 event |> Async.AwaitTask + | 2 -> do! handleDefense event |> Async.AwaitTask + | 3 -> do! handleTrainerStep3 event |> Async.AwaitTask + | 4 -> do! handleAttack event |> Async.AwaitTask | _ -> do! sendFollowUpMessage event "No action found" } diff --git a/DbService/DbService.fs b/DbService/DbService.fs index b04b81f..22aa8e4 100644 --- a/DbService/DbService.fs +++ b/DbService/DbService.fs @@ -63,7 +63,7 @@ let private playerMap (player : PlayerData) = { let private mapBack (player : PlayerEntry) : PlayerData = { DiscordId = player.DiscordId Name = player.Name - Arsenal = player.Arsenal |> Array.map (fun w -> Armoury.battleItems |> Array.find (fun w' -> w = w'.Id)) + Arsenal = player.Arsenal |> Array.map (fun w -> Armory.battleItems |> Array.find (fun w' -> w = w'.Id)) Actions = let atks = player.Attacks |> Array.map attackToAction let dfns = player.Defenses |> Array.map defenseToAction diff --git a/Shared/Shared.fs b/Shared/Shared.fs index 6d8da3c..c2156a8 100644 --- a/Shared/Shared.fs +++ b/Shared/Shared.fs @@ -77,7 +77,7 @@ module Types = Bank : int } -module Armoury = +module Armory = let battleItems = let file = System.IO.File.ReadAllText("Items.json") JsonConvert.DeserializeObject(file) @@ -95,7 +95,7 @@ module Player = let removeExpiredActions actions = actions |> Array.filter (fun (act : Action) -> - let item = Armoury.battleItems |> Array.find (fun w -> w.Id = act.ActionId) + let item = Armory.battleItems |> Array.find (fun w -> w.Id = act.ActionId) DateTime.UtcNow - act.Timestamp < TimeSpan.FromMinutes(int item.Cooldown)) let modifyBank player amount = { player with Bank = max (player.Bank + amount) 0 }