Move some stuff around
This commit is contained in:
parent
69545bf3a6
commit
ef3d5c58f5
@ -1,6 +1,5 @@
|
||||
module Degenz.Bot
|
||||
|
||||
open System
|
||||
open System.Threading.Tasks
|
||||
open DSharpPlus
|
||||
open DSharpPlus.SlashCommands
|
||||
|
@ -11,8 +11,8 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="paket.references" />
|
||||
<Compile Include="GameConfig.fs" />
|
||||
<Compile Include="GuildEnvironment.fs" />
|
||||
<Compile Include="Game.fs" />
|
||||
<Compile Include="Embeds.fs" />
|
||||
<Compile Include="Store.fs" />
|
||||
<Compile Include="Trainer.fs" />
|
||||
|
@ -1,7 +1,7 @@
|
||||
module Degenz.Embeds
|
||||
|
||||
open DSharpPlus.EventArgs
|
||||
open Degenz.Shared
|
||||
open Degenz.Types
|
||||
open DSharpPlus.Entities
|
||||
open AsciiTableFormatter
|
||||
|
||||
@ -34,7 +34,7 @@ let constructEmbed message =
|
||||
|
||||
let pickDefense actionId player =
|
||||
let buttons =
|
||||
constructButtons actionId (string player.DiscordId) (Player.shields player)
|
||||
Messaging.constructButtons actionId (string player.DiscordId) (Player.shields player)
|
||||
|> Seq.cast<DiscordComponent>
|
||||
|
||||
let embed =
|
||||
@ -50,7 +50,7 @@ let pickDefense actionId player =
|
||||
|
||||
let pickHack actionId attacker defender =
|
||||
let buttons =
|
||||
constructButtons actionId $"{defender.DiscordId}-{defender.Name}" (Player.hacks attacker)
|
||||
Messaging.constructButtons actionId $"{defender.DiscordId}-{defender.Name}" (Player.hacks attacker)
|
||||
|> Seq.cast<DiscordComponent>
|
||||
|
||||
let embed =
|
||||
|
15
Bot/Game.fs
Normal file
15
Bot/Game.fs
Normal file
@ -0,0 +1,15 @@
|
||||
module Degenz.Game
|
||||
|
||||
open System.Threading.Tasks
|
||||
open DSharpPlus.SlashCommands
|
||||
open Degenz.DbService
|
||||
|
||||
let executePlayerAction (ctx : InteractionContext) (dispatch : PlayerData -> Async<unit>) =
|
||||
async {
|
||||
let! playerResult = tryFindPlayer ctx.Member.Id
|
||||
match playerResult with
|
||||
| Some player -> do! dispatch player
|
||||
| None -> do! Messaging.sendSimpleResponse ctx "You are currently not a hacker, first use the /redpill command to become one"
|
||||
} |> Async.StartAsTask
|
||||
:> Task
|
||||
|
@ -1 +0,0 @@
|
||||
module Degenz.GameConfig
|
@ -7,8 +7,7 @@ open DSharpPlus.Entities
|
||||
open DSharpPlus.EventArgs
|
||||
open DSharpPlus.SlashCommands
|
||||
open Degenz
|
||||
open Degenz.Shared
|
||||
open Degenz.Store
|
||||
open Degenz.Messaging
|
||||
|
||||
let getTimeTillCooldownFinishes (timespan : TimeSpan) timestamp =
|
||||
let timeRemaining = timespan - (DateTime.UtcNow - timestamp)
|
||||
@ -26,8 +25,8 @@ let checkIfPlayerIsAttackingThemselves defender attacker =
|
||||
|
||||
let checkForExistingHack defenderId attacker =
|
||||
attacker.Actions
|
||||
|> removeExpiredActions
|
||||
|> getAttacksFlat
|
||||
|> Player.removeExpiredActions
|
||||
|> Player.getAttacksFlat
|
||||
|> Array.tryFind (fun (_,t,_) -> t.Id = defenderId)
|
||||
|> function
|
||||
| Some ( atk , target , _ ) ->
|
||||
@ -47,7 +46,7 @@ let checkIfHackHasCooldown hackId attacker =
|
||||
Ok attacker
|
||||
else
|
||||
let cooldown = getTimeTillCooldownFinishes (TimeSpan.FromMinutes(5)) mostRecentHackAttack
|
||||
let item = armoury |> Array.find (fun i -> i.Id = hackId)
|
||||
let item = Armoury.battleItems |> Array.find (fun i -> i.Id = hackId)
|
||||
Error $"{item.Name} is currently on cooldown, wait {cooldown} to use it again."
|
||||
|
||||
let checkIfInventoryIsEmpty attacker =
|
||||
@ -62,8 +61,8 @@ let calculateDamage (hack : BattleItem) (shield : BattleItem) =
|
||||
|
||||
let runHackerBattle defender hack =
|
||||
Player.defenses defender
|
||||
|> removeExpiredActions
|
||||
|> Array.map (fun dfn -> armoury |> Array.find (fun w -> w.Id = dfn.ActionId))
|
||||
|> Player.removeExpiredActions
|
||||
|> Array.map (fun dfn -> Armoury.battleItems |> Array.find (fun w -> w.Id = dfn.ActionId))
|
||||
|> Array.map (calculateDamage (hack))
|
||||
|> Array.contains Weak
|
||||
|
||||
@ -74,7 +73,7 @@ let updateCombatants attacker defender hack prize =
|
||||
let attack = { ActionId = int hack ; Type = Attack { Target = target ; Result = prize > 0<GBT> } ; Timestamp = DateTime.UtcNow }
|
||||
|
||||
[ DbService.updatePlayer <| updatePlayer prize attack attacker
|
||||
DbService.updatePlayer <| modifyPlayerBank defender -prize ]
|
||||
DbService.updatePlayer <| Player.modifyBank defender -prize ]
|
||||
|> Async.Parallel
|
||||
|> Async.Ignore
|
||||
|
||||
@ -115,11 +114,10 @@ let failedHack (event : ComponentInteractionCreateEventArgs) attacker defender h
|
||||
}
|
||||
|
||||
let attack (ctx : InteractionContext) (target : DiscordUser) =
|
||||
async {
|
||||
let! attacker = DbService.tryFindPlayer ctx.Member.Id
|
||||
Game.executePlayerAction ctx (fun attacker -> async {
|
||||
let! defender = DbService.tryFindPlayer target.Id
|
||||
match attacker , defender with
|
||||
| Some attacker , Some defender ->
|
||||
match defender with
|
||||
| Some defender ->
|
||||
let hackAttempt =
|
||||
checkForExistingHack defender.DiscordId attacker
|
||||
|> Result.bind checkIfInventoryIsEmpty
|
||||
@ -136,10 +134,8 @@ let attack (ctx : InteractionContext) (target : DiscordUser) =
|
||||
.AsEphemeral(true)
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||
|> Async.AwaitTask
|
||||
| None , _ -> do! notYetAHackerMsg ctx
|
||||
| _ , None -> do! createSimpleResponseAsync "Your target is not connected to the network, they must join first by using the /redpill command" ctx
|
||||
} |> Async.StartAsTask
|
||||
:> Task
|
||||
| None -> do! sendSimpleResponse ctx "Your target is not connected to the network, they must join first by using the /redpill command"
|
||||
})
|
||||
|
||||
let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||
async {
|
||||
@ -155,7 +151,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||
|> Result.bind (checkIfHackHasCooldown (int hack))
|
||||
|> function
|
||||
| Ok _ ->
|
||||
runHackerBattle defender (getItemFromArmoury <| int hack)
|
||||
runHackerBattle defender (Armoury.getItem (int hack))
|
||||
|> function
|
||||
| false -> successfulHack event attacker defender hack
|
||||
| true -> failedHack event attacker defender hack
|
||||
@ -175,10 +171,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||
}
|
||||
|
||||
let defend (ctx : InteractionContext) =
|
||||
async {
|
||||
let! player = DbService.tryFindPlayer ctx.Member.Id
|
||||
match player with
|
||||
| Some player ->
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
if Player.shields player |> Array.length > 0 then
|
||||
let embed = Embeds.pickDefense "Defend" player
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed)
|
||||
@ -189,9 +182,7 @@ let defend (ctx : InteractionContext) =
|
||||
builder.AsEphemeral true |> ignore
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||
|> Async.AwaitTask
|
||||
| None -> do! notYetAHackerMsg ctx
|
||||
} |> Async.StartAsTask
|
||||
:> Task
|
||||
})
|
||||
|
||||
let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
||||
async {
|
||||
@ -200,7 +191,7 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
||||
let! playerResult = DbService.tryFindPlayer event.User.Id
|
||||
match playerResult with
|
||||
| Some player ->
|
||||
let updatedDefenses = Player.defenses player |> removeExpiredActions
|
||||
let updatedDefenses = Player.defenses player |> Player.removeExpiredActions
|
||||
let alreadyUsedShield = updatedDefenses |> Array.exists (fun d -> d.ActionId = int shield)
|
||||
|
||||
match alreadyUsedShield , updatedDefenses.Length < 2 with
|
||||
|
@ -5,15 +5,15 @@ open DSharpPlus.Entities
|
||||
open DSharpPlus
|
||||
open DSharpPlus.SlashCommands
|
||||
open Degenz.Store
|
||||
open Degenz.Shared
|
||||
open Degenz.Types
|
||||
|
||||
module Commands =
|
||||
let newPlayer nickname (membr : uint64) =
|
||||
let rand = System.Random(System.Guid.NewGuid().GetHashCode())
|
||||
let randHack = rand.Next(0, 3)
|
||||
let randShield = rand.Next(6, 9)
|
||||
let hack = armoury |> Array.find (fun i -> i.Id = randHack)
|
||||
let shield = armoury |> Array.find (fun i -> i.Id = randShield)
|
||||
let hack = Armoury.battleItems |> Array.find (fun i -> i.Id = randHack)
|
||||
let shield = Armoury.battleItems |> Array.find (fun i -> i.Id = randShield)
|
||||
|
||||
{ DiscordId = membr
|
||||
Name = nickname
|
||||
@ -72,21 +72,16 @@ module Commands =
|
||||
// :> Task
|
||||
|
||||
let status (ctx : InteractionContext) =
|
||||
async {
|
||||
let! maybePlayer = DbService.tryFindPlayer ctx.Member.Id
|
||||
match maybePlayer with
|
||||
| Some player ->
|
||||
let updatedActions = removeExpiredActions player.Actions
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
let updatedActions = Player.removeExpiredActions player.Actions
|
||||
let updatedPlayer = { player with Actions = updatedActions }
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.IsEphemeral <- true
|
||||
builder.Content <- statusFormat updatedPlayer
|
||||
builder.Content <- Messaging.statusFormat updatedPlayer
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||
|> Async.AwaitTask
|
||||
do! DbService.updatePlayer updatedPlayer
|
||||
| None -> do! notYetAHackerMsg ctx
|
||||
} |> Async.StartAsTask
|
||||
:> Task
|
||||
})
|
||||
|
||||
type PlayerInteractions() =
|
||||
inherit ApplicationCommandModule ()
|
||||
|
@ -5,7 +5,7 @@ open System.Threading.Tasks
|
||||
open DSharpPlus
|
||||
open DSharpPlus.Entities
|
||||
open DSharpPlus.SlashCommands
|
||||
open Degenz.Shared
|
||||
open Degenz.Types
|
||||
|
||||
let slots = [| "https://i.ibb.co/pKqZdr7/cherry.png" ; "https://i.ibb.co/JnghQsL/lemon.jpg" ; "https://i.ibb.co/1JTFPSs/seven.png" |]
|
||||
|
||||
@ -13,11 +13,8 @@ type SlotMachine() =
|
||||
inherit ApplicationCommandModule ()
|
||||
|
||||
[<SlashCommand("spin", "Want to try your luck?")>]
|
||||
member this.AttackCommand (ctx : InteractionContext) =
|
||||
async {
|
||||
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
|
||||
match playerResult with
|
||||
| Some player ->
|
||||
member this.Spin (ctx : InteractionContext) =
|
||||
Game.executePlayerAction 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)]
|
||||
@ -73,8 +70,5 @@ type SlotMachine() =
|
||||
do! ctx.Interaction.CreateFollowupMessageAsync(builder)
|
||||
|> Async.AwaitTask
|
||||
|> Async.Ignore
|
||||
})
|
||||
|
||||
| None -> do! notYetAHackerMsg ctx
|
||||
|
||||
} |> Async.StartAsTask
|
||||
:> Task
|
||||
|
86
Bot/Store.fs
86
Bot/Store.fs
@ -8,54 +8,27 @@ open DSharpPlus.EventArgs
|
||||
open DSharpPlus.SlashCommands
|
||||
open Degenz
|
||||
open Degenz.Embeds
|
||||
open Degenz.Shared
|
||||
open Newtonsoft.Json
|
||||
|
||||
let getItemFromArmoury id = armoury |> Array.find (fun w -> w.Id = id)
|
||||
|
||||
let removeExpiredActions actions =
|
||||
actions
|
||||
|> Array.filter (fun (act : Action) ->
|
||||
let item = armoury |> Array.find (fun w -> w.Id = act.ActionId)
|
||||
DateTime.UtcNow - act.Timestamp < TimeSpan.FromMinutes(int item.Cooldown))
|
||||
open Degenz.Messaging
|
||||
|
||||
let viewStore (ctx : InteractionContext) =
|
||||
async {
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, Embeds.storeListing armoury)
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, Embeds.storeListing Armoury.battleItems)
|
||||
|> Async.AwaitTask
|
||||
} |> Async.StartAsTask
|
||||
:> Task
|
||||
|
||||
let buyItem (ctx : InteractionContext) itemId =
|
||||
async {
|
||||
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
|
||||
let item = armoury |> Array.find (fun w -> w.Id = itemId)
|
||||
match playerResult with
|
||||
| Some player ->
|
||||
let newBalance = player.Bank - item.Cost
|
||||
if newBalance >= 0<GBT> then
|
||||
let playerHasItem = player.Arsenal |> Array.exists (fun w -> item.Id = w.Id)
|
||||
if not playerHasItem then
|
||||
let p = { player with Bank = newBalance ; Arsenal = Array.append [| item |] player.Arsenal }
|
||||
do! DbService.updatePlayer p
|
||||
do! createSimpleResponseAsync $"Successfully purchased {item.Name}! You now have {newBalance} remaining" ctx
|
||||
else
|
||||
do! createSimpleResponseAsync $"You already own this item!" ctx
|
||||
else
|
||||
do! createSimpleResponseAsync $"You do not have sufficient funds to buy this item! Current balance: {player.Bank} GBT" ctx
|
||||
| None -> do! notYetAHackerMsg ctx
|
||||
} |> Async.StartAsTask
|
||||
:> Task
|
||||
let buyItem (ctx : InteractionContext) itemType =
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
let embed = DiscordEmbedBuilder()
|
||||
|
||||
let constructItemButtons playerInfo itemType (items : 'a array) =
|
||||
items
|
||||
|> Seq.map (fun item -> DiscordButtonComponent(ButtonStyle.Primary, $"{playerInfo}-{itemType}-{item}", $"{item}"))
|
||||
// embed.Fields
|
||||
|
||||
do! ctx.CreateResponseAsync(embed, true)
|
||||
|> Async.AwaitTask
|
||||
})
|
||||
|
||||
let sell (ctx : InteractionContext) =
|
||||
async {
|
||||
let! playerResult = DbService.tryFindPlayer ctx.Member.Id
|
||||
match playerResult with
|
||||
| Some player ->
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
let hasInventoryToSell = Array.length player.Arsenal > 0
|
||||
if hasInventoryToSell then
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
@ -74,17 +47,12 @@ let sell (ctx : InteractionContext) =
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||
|> Async.AwaitTask
|
||||
else
|
||||
do! createSimpleResponseAsync "You currently have no inventory to sell" ctx
|
||||
| None -> do! notYetAHackerMsg ctx
|
||||
return ()
|
||||
} |> Async.StartAsTask
|
||||
:> Task
|
||||
|
||||
let updateArsenal player salePrice updatedArsenal = { player with Bank = player.Bank + salePrice ; Arsenal = updatedArsenal }
|
||||
do! sendSimpleResponse ctx "You currently have no inventory to sell"
|
||||
})
|
||||
|
||||
let sellItem (event : ComponentInteractionCreateEventArgs) player itemId =
|
||||
async {
|
||||
let item = armoury |> Array.find (fun i -> i.Id = itemId)
|
||||
let item = Armoury.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()
|
||||
@ -94,6 +62,22 @@ let sellItem (event : ComponentInteractionCreateEventArgs) player itemId =
|
||||
|> Async.AwaitTask
|
||||
}
|
||||
|
||||
let handleBuyItem (ctx : InteractionContext) itemId =
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
let item = Armoury.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)
|
||||
if not playerHasItem then
|
||||
let p = { player with Bank = newBalance ; Arsenal = Array.append [| item |] player.Arsenal }
|
||||
do! DbService.updatePlayer p
|
||||
do! sendSimpleResponse ctx $"Successfully purchased {item.Name}! You now have {newBalance} remaining"
|
||||
else
|
||||
do! sendSimpleResponse ctx $"You already own this item!"
|
||||
else
|
||||
do! sendSimpleResponse ctx $"You do not have sufficient funds to buy this item! Current balance: {player.Bank} GBT"
|
||||
})
|
||||
|
||||
let handleSellButtonEvents (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
||||
async {
|
||||
let! playerResult = DbService.tryFindPlayer event.User.Id
|
||||
@ -112,17 +96,15 @@ let handleSellButtonEvents (_ : DiscordClient) (event : ComponentInteractionCrea
|
||||
|
||||
type Store() =
|
||||
inherit ApplicationCommandModule ()
|
||||
// [<SlashCommand("view-store", "View items available for purchase")>]
|
||||
|
||||
[<SlashCommand("view-store", "View items available for purchase")>]
|
||||
member _.ViewStore (ctx : InteractionContext) = viewStore ctx
|
||||
// member _.ViewStore (ctx : InteractionContext) = viewStore ctx
|
||||
|
||||
[<SlashCommand("buy-hack", "Purchase a hack attack you can use to earn GoodBoyTokenz")>]
|
||||
member _.BuyHack (ctx : InteractionContext, [<Option("hack-id", "The ID of the hack you wish to purchase")>] hackId : HackId) =
|
||||
buyItem ctx (int hackId)
|
||||
member _.BuyHack (ctx : InteractionContext) = buyItem ctx Hack
|
||||
|
||||
[<SlashCommand("buy-shield", "Purchase a hack shield so you can protect your GoodBoyTokenz")>]
|
||||
member this.BuyShield (ctx : InteractionContext, [<Option("shield-id", "The ID of the shield you wish to purchase")>] shieldId : ShieldId) =
|
||||
buyItem ctx (int shieldId)
|
||||
member this.BuyShield (ctx : InteractionContext) = buyItem ctx Shield
|
||||
|
||||
[<SlashCommand("sell", "Sell an item in your inventory for GoodBoyTokenz")>]
|
||||
member this.SellItem (ctx : InteractionContext) = sell ctx
|
||||
|
@ -5,11 +5,11 @@ open DSharpPlus
|
||||
open DSharpPlus.Entities
|
||||
open DSharpPlus.EventArgs
|
||||
open DSharpPlus.SlashCommands
|
||||
open Degenz.Shared
|
||||
open Degenz.Store
|
||||
open Degenz.Types
|
||||
open Degenz.Messaging
|
||||
|
||||
let defaultHack = armoury |> Array.find (fun i -> i.Id = int HackId.Virus)
|
||||
let defaultShield = armoury |> Array.find (fun i -> i.Id = int ShieldId.Firewall)
|
||||
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 sendInitialEmbed (client : DiscordClient) =
|
||||
async {
|
||||
@ -41,10 +41,10 @@ let handleTrainerStep1 (event : ComponentInteractionCreateEventArgs) =
|
||||
|> Async.AwaitTask
|
||||
match maybePlayer with
|
||||
| Some _ ->
|
||||
do! Message.sendFollowUpMessageWithButton event step1Msg
|
||||
do! sendFollowUpMessageWithButton event step1Msg
|
||||
| None ->
|
||||
let msg = "Looks like an error occurred, you're not a registered degenerate. Please contact a moderator."
|
||||
do! Message.sendFollowUpMessage event msg
|
||||
do! sendFollowUpMessage event msg
|
||||
}
|
||||
|
||||
let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) =
|
||||
@ -53,19 +53,19 @@ let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) =
|
||||
match result with
|
||||
| Some player ->
|
||||
let weaponName = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name
|
||||
do! Message.updateMessageWithGreyedOutButtons event step1Msg
|
||||
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! Message.sendFollowUpMessage event
|
||||
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! Message.sendFollowUpMessage event $"Something went wrong, please contact a moderator"
|
||||
do! sendFollowUpMessage event $"Something went wrong, please contact a moderator"
|
||||
}
|
||||
|
||||
let defend (ctx : InteractionContext) =
|
||||
@ -100,7 +100,7 @@ let handleDefenseMsg = {
|
||||
}
|
||||
|
||||
let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
||||
let sendMessage' = Message.sendFollowUpMessage event
|
||||
let sendMessage' = sendFollowUpMessage event
|
||||
async {
|
||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|
||||
|> Async.AwaitTask
|
||||
@ -116,7 +116,7 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
||||
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! Message.sendFollowUpMessageWithButton event handleDefenseMsg
|
||||
do! sendFollowUpMessageWithButton event handleDefenseMsg
|
||||
| None ->
|
||||
do! sendMessage' $"Something went wrong, please contact a moderator"
|
||||
}
|
||||
@ -127,19 +127,19 @@ let handleTrainerStep4 (event : ComponentInteractionCreateEventArgs) =
|
||||
match result with
|
||||
| Some player ->
|
||||
let weaponName = Player.hacks player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name
|
||||
do! Message.updateMessageWithGreyedOutButtons event handleDefenseMsg
|
||||
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"
|
||||
|
||||
do! Message.sendFollowUpMessage event
|
||||
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! Message.sendInteractionEvent event $"Something went wrong, please contact a moderator"
|
||||
do! sendInteractionEvent event $"Something went wrong, please contact a moderator"
|
||||
}
|
||||
|
||||
let attack (ctx : InteractionContext) (target : DiscordUser) =
|
||||
@ -184,7 +184,7 @@ let handleAttackMsg = {
|
||||
}
|
||||
|
||||
let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||
let sendMessage' = Message.sendFollowUpMessage event
|
||||
let sendMessage' = sendFollowUpMessage event
|
||||
async {
|
||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|
||||
|> Async.AwaitTask
|
||||
@ -200,7 +200,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||
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! Message.sendFollowUpMessageWithButton event handleAttackMsg
|
||||
do! sendFollowUpMessageWithButton event handleAttackMsg
|
||||
| None ->
|
||||
do! sendMessage' $"Something went wrong, please contact a moderator"
|
||||
}
|
||||
@ -214,7 +214,7 @@ let handleTrainerStep6 (event : ComponentInteractionCreateEventArgs) =
|
||||
let builder = DiscordFollowupMessageBuilder()
|
||||
builder.IsEphemeral <- true
|
||||
builder.Content <- "Get out of here!"
|
||||
do! Message.updateMessageWithGreyedOutButtons event handleAttackMsg
|
||||
do! updateMessageWithGreyedOutButtons event handleAttackMsg
|
||||
do! event.Interaction.CreateFollowupMessageAsync(builder)
|
||||
|> Async.AwaitTask
|
||||
|> Async.Ignore
|
||||
@ -230,6 +230,6 @@ let handleButtonEvent (event : ComponentInteractionCreateEventArgs) =
|
||||
| 4 -> do! handleTrainerStep4 event
|
||||
| 5 -> do! handleAttack event
|
||||
| 6 -> do! handleTrainerStep6 event
|
||||
| _ -> do! Message.sendFollowUpMessage event "No action found"
|
||||
| _ -> do! sendFollowUpMessage event "No action found"
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
open System
|
||||
open System.Collections.Generic
|
||||
open Degenz.Shared
|
||||
open System.Threading.Tasks
|
||||
open Degenz.Types
|
||||
open MongoDB.Bson
|
||||
open MongoDB.Bson.Serialization
|
||||
open MongoDB.Driver
|
||||
@ -62,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 |> Array.find (fun w' -> w = w'.Id))
|
||||
Arsenal = player.Arsenal |> Array.map (fun w -> Armoury.battleItems |> Array.find (fun w' -> w = w'.Id))
|
||||
Actions =
|
||||
let atks = player.Attacks |> Array.map attackToAction
|
||||
let dfns = player.Defenses |> Array.map defenseToAction
|
||||
@ -113,6 +114,7 @@ let updatePlayer (player : PlayerData) =
|
||||
return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
|
||||
}
|
||||
|
||||
|
||||
//let getTopPlayers amount =
|
||||
// async {
|
||||
// return! players.FindAsync()
|
||||
|
@ -1,4 +1,4 @@
|
||||
module Degenz.Shared
|
||||
namespace Degenz
|
||||
|
||||
open System
|
||||
open DSharpPlus
|
||||
@ -7,6 +7,9 @@ open DSharpPlus.EventArgs
|
||||
open DSharpPlus.SlashCommands
|
||||
open Newtonsoft.Json
|
||||
|
||||
[<Microsoft.FSharp.Core.AutoOpen>]
|
||||
module Types =
|
||||
|
||||
[<Measure>]
|
||||
type mins
|
||||
|
||||
@ -73,6 +76,14 @@ type PlayerData =
|
||||
Actions : Action array
|
||||
Bank : int<GBT> }
|
||||
|
||||
|
||||
module Armoury =
|
||||
let battleItems =
|
||||
let file = System.IO.File.ReadAllText("Items.json")
|
||||
JsonConvert.DeserializeObject<BattleItem array>(file)
|
||||
|
||||
let getItem itemId = battleItems |> Array.find (fun w -> w.Id = itemId)
|
||||
|
||||
module Player =
|
||||
let hacks player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Hack)
|
||||
let shields player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Shield)
|
||||
@ -81,24 +92,24 @@ module Player =
|
||||
|> Array.choose (fun act -> match act.Type with Attack ar -> Some (act,ar.Target,ar.Result) | Defense -> None)
|
||||
let defenses player = player.Actions |> Array.filter (fun act -> match act.Type with Defense _ -> true | _ -> false)
|
||||
|
||||
let removeExpiredActions actions =
|
||||
actions
|
||||
|> Array.filter (fun (act : Action) ->
|
||||
let item = Armoury.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> }
|
||||
|
||||
let getAttacksFlat actions = actions |> Array.choose (fun act -> match act.Type with Attack ar -> Some (act,ar.Target,ar.Result) | Defense -> None)
|
||||
|
||||
let createSimpleResponseAsync msg (ctx: InteractionContext) =
|
||||
async {
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.Content <- msg
|
||||
builder.AsEphemeral true |> ignore
|
||||
|
||||
do!
|
||||
ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||
|> Async.AwaitTask
|
||||
module Messaging =
|
||||
type InteractiveMessage = {
|
||||
ButtonId : string
|
||||
ButtonText : string
|
||||
Message : string
|
||||
}
|
||||
|
||||
let notYetAHackerMsg =
|
||||
createSimpleResponseAsync "You are currently not a hacker, first use the /redpill command to become one"
|
||||
|
||||
let hackDescription = ""
|
||||
|
||||
let statusFormat p =
|
||||
$"Hacks: {Player.hacks p |> Array.toList}
|
||||
Shields: {Player.shields p |> Array.toList}
|
||||
@ -110,19 +121,15 @@ let constructButtons (actionType: string) (playerInfo: string) (weapons: BattleI
|
||||
weapons
|
||||
|> Array.map (fun w -> DiscordButtonComponent(ButtonStyle.Success, $"{actionType}-{w.Id}-{playerInfo}", $"{w.Name}"))
|
||||
|
||||
let modifyPlayerBank player amount = { player with Bank = max (player.Bank + amount) 0<GBT> }
|
||||
|
||||
let armoury =
|
||||
let file = System.IO.File.ReadAllText("Items.json")
|
||||
JsonConvert.DeserializeObject<BattleItem array>(file)
|
||||
|
||||
type InteractiveMessage = {
|
||||
ButtonId : string
|
||||
ButtonText : string
|
||||
Message : string
|
||||
let sendSimpleResponse (ctx: InteractionContext) msg =
|
||||
async {
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.Content <- msg
|
||||
builder.AsEphemeral true |> ignore
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||
|> Async.AwaitTask
|
||||
}
|
||||
|
||||
module Message =
|
||||
let sendFollowUpMessage (event : ComponentInteractionCreateEventArgs) msg =
|
||||
async {
|
||||
let builder = DiscordFollowupMessageBuilder()
|
||||
|
Loading…
x
Reference in New Issue
Block a user