Implement new Trainer improvements and clean up a few more things

This commit is contained in:
Joseph Ferano 2022-02-01 22:45:27 +07:00
parent ef3d5c58f5
commit e772a6d6f3
11 changed files with 135 additions and 200 deletions

View File

@ -74,7 +74,7 @@ let run (client : DiscordClient) =
do! client.ConnectAsync () |> Async.AwaitTask
}
//Trainer.sendInitialEmbed hackerBattleBot
Trainer.sendInitialEmbed hackerBattleBot
clients
|> Array.map run

View File

@ -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<HackId>(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)

View File

@ -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<unit>) =
let HackPrize = 10<GBT>
let ShieldPrize = 5<GBT>
let executePlayerInteraction (ctx : InteractionContext) (dispatch : PlayerData -> Async<unit>) =
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<unit>) =
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

View File

@ -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"

View File

@ -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<GBT>
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<GBT>
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
[<SlashCommand("defend", "Create a passive defense that will last 24 hours")>]
member this.DefendCommand (ctx : InteractionContext) =
[<SlashCommand("shield", "Create a passive defense that will last 24 hours")>]
member this.ShieldCommand (ctx : InteractionContext) =
if ctx.Channel.Id = GuildEnvironment.channelTraining then
Trainer.defend ctx
else

View File

@ -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()

View File

@ -14,7 +14,7 @@ type SlotMachine() =
[<SlashCommand("spin", "Want to try your luck?")>]
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)]

View File

@ -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<GBT> then
let playerHasItem = player.Arsenal |> Array.exists (fun w -> item.Id = w.Id)

View File

@ -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 lets **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, youre 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"
}

View File

@ -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

View File

@ -77,7 +77,7 @@ module Types =
Bank : int<GBT> }
module Armoury =
module Armory =
let battleItems =
let file = System.IO.File.ReadAllText("Items.json")
JsonConvert.DeserializeObject<BattleItem array>(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<GBT> }