Implement new Trainer improvements and clean up a few more things
This commit is contained in:
parent
ef3d5c58f5
commit
e772a6d6f3
@ -74,7 +74,7 @@ let run (client : DiscordClient) =
|
||||
do! client.ConnectAsync () |> Async.AwaitTask
|
||||
}
|
||||
|
||||
//Trainer.sendInitialEmbed hackerBattleBot
|
||||
Trainer.sendInitialEmbed hackerBattleBot
|
||||
|
||||
clients
|
||||
|> Array.map run
|
||||
|
@ -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)
|
||||
|
||||
|
16
Bot/Game.fs
16
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<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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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)]
|
||||
|
12
Bot/Store.fs
12
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<GBT> then
|
||||
let playerHasItem = player.Arsenal |> Array.exists (fun w -> item.Id = w.Id)
|
||||
|
252
Bot/Trainer.fs
252
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"
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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> }
|
||||
|
Loading…
x
Reference in New Issue
Block a user