Move some stuff around
This commit is contained in:
		
							parent
							
								
									69545bf3a6
								
							
						
					
					
						commit
						ef3d5c58f5
					
				@ -1,6 +1,5 @@
 | 
				
			|||||||
module Degenz.Bot
 | 
					module Degenz.Bot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
open System
 | 
					 | 
				
			||||||
open System.Threading.Tasks
 | 
					open System.Threading.Tasks
 | 
				
			||||||
open DSharpPlus
 | 
					open DSharpPlus
 | 
				
			||||||
open DSharpPlus.SlashCommands
 | 
					open DSharpPlus.SlashCommands
 | 
				
			||||||
 | 
				
			|||||||
@ -11,8 +11,8 @@
 | 
				
			|||||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
					      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
				
			||||||
    </Content>
 | 
					    </Content>
 | 
				
			||||||
    <Content Include="paket.references" />
 | 
					    <Content Include="paket.references" />
 | 
				
			||||||
    <Compile Include="GameConfig.fs" />
 | 
					 | 
				
			||||||
    <Compile Include="GuildEnvironment.fs" />
 | 
					    <Compile Include="GuildEnvironment.fs" />
 | 
				
			||||||
 | 
					    <Compile Include="Game.fs" />
 | 
				
			||||||
    <Compile Include="Embeds.fs" />
 | 
					    <Compile Include="Embeds.fs" />
 | 
				
			||||||
    <Compile Include="Store.fs" />
 | 
					    <Compile Include="Store.fs" />
 | 
				
			||||||
    <Compile Include="Trainer.fs" />
 | 
					    <Compile Include="Trainer.fs" />
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
module Degenz.Embeds
 | 
					module Degenz.Embeds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
open DSharpPlus.EventArgs
 | 
					open DSharpPlus.EventArgs
 | 
				
			||||||
open Degenz.Shared
 | 
					open Degenz.Types
 | 
				
			||||||
open DSharpPlus.Entities
 | 
					open DSharpPlus.Entities
 | 
				
			||||||
open AsciiTableFormatter
 | 
					open AsciiTableFormatter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -34,7 +34,7 @@ let constructEmbed message =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
let pickDefense actionId player =
 | 
					let pickDefense actionId player =
 | 
				
			||||||
    let buttons =
 | 
					    let buttons =
 | 
				
			||||||
        constructButtons actionId (string player.DiscordId) (Player.shields player)
 | 
					        Messaging.constructButtons actionId (string player.DiscordId) (Player.shields player)
 | 
				
			||||||
        |> Seq.cast<DiscordComponent>
 | 
					        |> Seq.cast<DiscordComponent>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let embed =
 | 
					    let embed =
 | 
				
			||||||
@ -50,7 +50,7 @@ let pickDefense actionId player =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
let pickHack actionId attacker defender =
 | 
					let pickHack actionId attacker defender =
 | 
				
			||||||
    let buttons =
 | 
					    let buttons =
 | 
				
			||||||
        constructButtons actionId $"{defender.DiscordId}-{defender.Name}" (Player.hacks attacker)
 | 
					        Messaging.constructButtons actionId $"{defender.DiscordId}-{defender.Name}" (Player.hacks attacker)
 | 
				
			||||||
        |> Seq.cast<DiscordComponent>
 | 
					        |> Seq.cast<DiscordComponent>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let embed =
 | 
					    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.EventArgs
 | 
				
			||||||
open DSharpPlus.SlashCommands
 | 
					open DSharpPlus.SlashCommands
 | 
				
			||||||
open Degenz
 | 
					open Degenz
 | 
				
			||||||
open Degenz.Shared
 | 
					open Degenz.Messaging
 | 
				
			||||||
open Degenz.Store
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
let getTimeTillCooldownFinishes (timespan : TimeSpan) timestamp =
 | 
					let getTimeTillCooldownFinishes (timespan : TimeSpan) timestamp =
 | 
				
			||||||
    let timeRemaining = timespan - (DateTime.UtcNow - timestamp)
 | 
					    let timeRemaining = timespan - (DateTime.UtcNow - timestamp)
 | 
				
			||||||
@ -26,8 +25,8 @@ let checkIfPlayerIsAttackingThemselves defender attacker  =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
let checkForExistingHack defenderId attacker =
 | 
					let checkForExistingHack defenderId attacker =
 | 
				
			||||||
    attacker.Actions
 | 
					    attacker.Actions
 | 
				
			||||||
    |> removeExpiredActions
 | 
					    |> Player.removeExpiredActions
 | 
				
			||||||
    |> getAttacksFlat
 | 
					    |> Player.getAttacksFlat
 | 
				
			||||||
    |> Array.tryFind (fun (_,t,_) -> t.Id = defenderId)
 | 
					    |> Array.tryFind (fun (_,t,_) -> t.Id = defenderId)
 | 
				
			||||||
    |> function
 | 
					    |> function
 | 
				
			||||||
       | Some ( atk , target , _ ) ->
 | 
					       | Some ( atk , target , _ ) ->
 | 
				
			||||||
@ -47,7 +46,7 @@ let checkIfHackHasCooldown hackId attacker =
 | 
				
			|||||||
        Ok attacker
 | 
					        Ok attacker
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
       let cooldown = getTimeTillCooldownFinishes (TimeSpan.FromMinutes(5)) mostRecentHackAttack
 | 
					       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."
 | 
					       Error $"{item.Name} is currently on cooldown, wait {cooldown} to use it again."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let checkIfInventoryIsEmpty attacker =
 | 
					let checkIfInventoryIsEmpty attacker =
 | 
				
			||||||
@ -62,8 +61,8 @@ let calculateDamage (hack : BattleItem) (shield : BattleItem) =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
let runHackerBattle defender hack =
 | 
					let runHackerBattle defender hack =
 | 
				
			||||||
    Player.defenses defender
 | 
					    Player.defenses defender
 | 
				
			||||||
    |> removeExpiredActions
 | 
					    |> Player.removeExpiredActions
 | 
				
			||||||
    |> Array.map (fun dfn -> armoury |> Array.find (fun w -> w.Id = dfn.ActionId))
 | 
					    |> Array.map (fun dfn -> Armoury.battleItems |> Array.find (fun w -> w.Id = dfn.ActionId))
 | 
				
			||||||
    |> Array.map (calculateDamage (hack))
 | 
					    |> Array.map (calculateDamage (hack))
 | 
				
			||||||
    |> Array.contains Weak
 | 
					    |> 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 }
 | 
					    let attack = { ActionId = int hack ; Type = Attack { Target = target ; Result = prize > 0<GBT> } ; Timestamp = DateTime.UtcNow }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [ DbService.updatePlayer <| updatePlayer prize attack attacker
 | 
					    [ DbService.updatePlayer <| updatePlayer prize attack attacker
 | 
				
			||||||
      DbService.updatePlayer <| modifyPlayerBank defender -prize ]
 | 
					      DbService.updatePlayer <| Player.modifyBank defender -prize ]
 | 
				
			||||||
    |> Async.Parallel
 | 
					    |> Async.Parallel
 | 
				
			||||||
    |> Async.Ignore
 | 
					    |> Async.Ignore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -115,11 +114,10 @@ let failedHack (event : ComponentInteractionCreateEventArgs) attacker defender h
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let attack (ctx : InteractionContext) (target : DiscordUser) =
 | 
					let attack (ctx : InteractionContext) (target : DiscordUser) =
 | 
				
			||||||
    async {
 | 
					    Game.executePlayerAction ctx (fun attacker -> async {
 | 
				
			||||||
        let! attacker = DbService.tryFindPlayer ctx.Member.Id
 | 
					 | 
				
			||||||
        let! defender = DbService.tryFindPlayer target.Id
 | 
					        let! defender = DbService.tryFindPlayer target.Id
 | 
				
			||||||
        match attacker , defender with
 | 
					        match defender with
 | 
				
			||||||
        | Some attacker , Some defender ->
 | 
					        | Some defender ->
 | 
				
			||||||
            let hackAttempt =
 | 
					            let hackAttempt =
 | 
				
			||||||
                checkForExistingHack defender.DiscordId attacker
 | 
					                checkForExistingHack defender.DiscordId attacker
 | 
				
			||||||
                |> Result.bind checkIfInventoryIsEmpty
 | 
					                |> Result.bind checkIfInventoryIsEmpty
 | 
				
			||||||
@ -136,10 +134,8 @@ let attack (ctx : InteractionContext) (target : DiscordUser) =
 | 
				
			|||||||
                        .AsEphemeral(true)
 | 
					                        .AsEphemeral(true)
 | 
				
			||||||
                do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
 | 
					                do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
 | 
				
			||||||
                    |> Async.AwaitTask
 | 
					                    |> Async.AwaitTask
 | 
				
			||||||
        | None , _ -> do! notYetAHackerMsg ctx
 | 
					        | None -> do! sendSimpleResponse ctx "Your target is not connected to the network, they must join first by using the /redpill command"
 | 
				
			||||||
        | _ , None -> do! createSimpleResponseAsync "Your target is not connected to the network, they must join first by using the /redpill command" ctx
 | 
					    })
 | 
				
			||||||
    } |> Async.StartAsTask
 | 
					 | 
				
			||||||
    :> Task
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
let handleAttack (event : ComponentInteractionCreateEventArgs) =
 | 
					let handleAttack (event : ComponentInteractionCreateEventArgs) =
 | 
				
			||||||
    async {
 | 
					    async {
 | 
				
			||||||
@ -155,7 +151,7 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
 | 
				
			|||||||
                |> Result.bind (checkIfHackHasCooldown (int hack))
 | 
					                |> Result.bind (checkIfHackHasCooldown (int hack))
 | 
				
			||||||
                |> function
 | 
					                |> function
 | 
				
			||||||
                   | Ok _ ->
 | 
					                   | Ok _ ->
 | 
				
			||||||
                       runHackerBattle defender (getItemFromArmoury <| int hack)
 | 
					                       runHackerBattle defender (Armoury.getItem (int hack))
 | 
				
			||||||
                       |> function
 | 
					                       |> function
 | 
				
			||||||
                          | false -> successfulHack event attacker defender hack
 | 
					                          | false -> successfulHack event attacker defender hack
 | 
				
			||||||
                          | true -> failedHack event attacker defender hack
 | 
					                          | true -> failedHack event attacker defender hack
 | 
				
			||||||
@ -175,23 +171,18 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let defend (ctx : InteractionContext) =
 | 
					let defend (ctx : InteractionContext) =
 | 
				
			||||||
    async {
 | 
					    Game.executePlayerAction ctx (fun player -> async {
 | 
				
			||||||
        let! player = DbService.tryFindPlayer ctx.Member.Id
 | 
					        if Player.shields player |> Array.length > 0 then
 | 
				
			||||||
        match player with
 | 
					            let embed = Embeds.pickDefense "Defend" player
 | 
				
			||||||
        | Some player ->
 | 
					            do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed)
 | 
				
			||||||
            if Player.shields player |> Array.length > 0 then
 | 
					                |> Async.AwaitTask
 | 
				
			||||||
                let embed = Embeds.pickDefense "Defend" player
 | 
					        else
 | 
				
			||||||
                do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed)
 | 
					            let builder = DiscordInteractionResponseBuilder()
 | 
				
			||||||
                    |> Async.AwaitTask
 | 
					            builder.Content <- $"You currently do not have any Shields to protect your system. Please go to the armoury and purchase one."
 | 
				
			||||||
            else
 | 
					            builder.AsEphemeral true |> ignore
 | 
				
			||||||
                let builder = DiscordInteractionResponseBuilder()
 | 
					            do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
 | 
				
			||||||
                builder.Content <- $"You currently do not have any Shields to protect your system. Please go to the armoury and purchase one."
 | 
					                |> Async.AwaitTask
 | 
				
			||||||
                builder.AsEphemeral true |> ignore
 | 
					    })
 | 
				
			||||||
                do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
 | 
					 | 
				
			||||||
                    |> Async.AwaitTask
 | 
					 | 
				
			||||||
        | None -> do! notYetAHackerMsg ctx
 | 
					 | 
				
			||||||
    } |> Async.StartAsTask
 | 
					 | 
				
			||||||
    :> Task
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
let handleDefense (event : ComponentInteractionCreateEventArgs) =
 | 
					let handleDefense (event : ComponentInteractionCreateEventArgs) =
 | 
				
			||||||
    async {
 | 
					    async {
 | 
				
			||||||
@ -200,7 +191,7 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
 | 
				
			|||||||
        let! playerResult = DbService.tryFindPlayer event.User.Id
 | 
					        let! playerResult = DbService.tryFindPlayer event.User.Id
 | 
				
			||||||
        match playerResult with
 | 
					        match playerResult with
 | 
				
			||||||
        | Some player ->
 | 
					        | 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)
 | 
					            let alreadyUsedShield = updatedDefenses |> Array.exists (fun d -> d.ActionId = int shield)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            match alreadyUsedShield , updatedDefenses.Length < 2 with
 | 
					            match alreadyUsedShield , updatedDefenses.Length < 2 with
 | 
				
			||||||
 | 
				
			|||||||
@ -5,15 +5,15 @@ open DSharpPlus.Entities
 | 
				
			|||||||
open DSharpPlus
 | 
					open DSharpPlus
 | 
				
			||||||
open DSharpPlus.SlashCommands
 | 
					open DSharpPlus.SlashCommands
 | 
				
			||||||
open Degenz.Store
 | 
					open Degenz.Store
 | 
				
			||||||
open Degenz.Shared
 | 
					open Degenz.Types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module Commands =
 | 
					module Commands =
 | 
				
			||||||
    let newPlayer nickname (membr : uint64) =
 | 
					    let newPlayer nickname (membr : uint64) =
 | 
				
			||||||
        let rand = System.Random(System.Guid.NewGuid().GetHashCode())
 | 
					        let rand = System.Random(System.Guid.NewGuid().GetHashCode())
 | 
				
			||||||
        let randHack = rand.Next(0, 3)
 | 
					        let randHack = rand.Next(0, 3)
 | 
				
			||||||
        let randShield = rand.Next(6, 9)
 | 
					        let randShield = rand.Next(6, 9)
 | 
				
			||||||
        let hack = armoury |> Array.find (fun i -> i.Id = randHack)
 | 
					        let hack = Armoury.battleItems |> Array.find (fun i -> i.Id = randHack)
 | 
				
			||||||
        let shield = armoury |> Array.find (fun i -> i.Id = randShield)
 | 
					        let shield = Armoury.battleItems |> Array.find (fun i -> i.Id = randShield)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { DiscordId = membr
 | 
					        { DiscordId = membr
 | 
				
			||||||
          Name = nickname
 | 
					          Name = nickname
 | 
				
			||||||
@ -72,21 +72,16 @@ module Commands =
 | 
				
			|||||||
//        :> Task
 | 
					//        :> Task
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let status (ctx : InteractionContext) =
 | 
					    let status (ctx : InteractionContext) =
 | 
				
			||||||
        async {
 | 
					        Game.executePlayerAction ctx (fun player -> async {
 | 
				
			||||||
            let! maybePlayer = DbService.tryFindPlayer ctx.Member.Id
 | 
					            let updatedActions = Player.removeExpiredActions player.Actions
 | 
				
			||||||
            match maybePlayer with
 | 
					            let updatedPlayer = { player with Actions = updatedActions }
 | 
				
			||||||
            | Some player ->
 | 
					            let builder = DiscordInteractionResponseBuilder()
 | 
				
			||||||
                let updatedActions = removeExpiredActions player.Actions
 | 
					            builder.IsEphemeral <- true
 | 
				
			||||||
                let updatedPlayer = { player with Actions = updatedActions }
 | 
					            builder.Content <- Messaging.statusFormat updatedPlayer
 | 
				
			||||||
                let builder = DiscordInteractionResponseBuilder()
 | 
					            do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
 | 
				
			||||||
                builder.IsEphemeral <- true
 | 
					                |> Async.AwaitTask
 | 
				
			||||||
                builder.Content <- statusFormat updatedPlayer
 | 
					            do! DbService.updatePlayer updatedPlayer
 | 
				
			||||||
                do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
 | 
					        })
 | 
				
			||||||
                    |> Async.AwaitTask
 | 
					 | 
				
			||||||
                do! DbService.updatePlayer updatedPlayer
 | 
					 | 
				
			||||||
            | None -> do! notYetAHackerMsg ctx
 | 
					 | 
				
			||||||
        } |> Async.StartAsTask
 | 
					 | 
				
			||||||
        :> Task
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type PlayerInteractions() =
 | 
					type PlayerInteractions() =
 | 
				
			||||||
    inherit ApplicationCommandModule ()
 | 
					    inherit ApplicationCommandModule ()
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ open System.Threading.Tasks
 | 
				
			|||||||
open DSharpPlus
 | 
					open DSharpPlus
 | 
				
			||||||
open DSharpPlus.Entities
 | 
					open DSharpPlus.Entities
 | 
				
			||||||
open DSharpPlus.SlashCommands
 | 
					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" |]
 | 
					let slots = [| "https://i.ibb.co/pKqZdr7/cherry.png" ; "https://i.ibb.co/JnghQsL/lemon.jpg" ; "https://i.ibb.co/1JTFPSs/seven.png" |]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -13,68 +13,62 @@ type SlotMachine() =
 | 
				
			|||||||
    inherit ApplicationCommandModule ()
 | 
					    inherit ApplicationCommandModule ()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [<SlashCommand("spin", "Want to try your luck?")>]
 | 
					    [<SlashCommand("spin", "Want to try your luck?")>]
 | 
				
			||||||
    member this.AttackCommand (ctx : InteractionContext) =
 | 
					    member this.Spin (ctx : InteractionContext) =
 | 
				
			||||||
        async {
 | 
					        Game.executePlayerAction ctx (fun player -> async {
 | 
				
			||||||
            let! playerResult = DbService.tryFindPlayer ctx.Member.Id
 | 
					            let sleepTime = 1000
 | 
				
			||||||
            match playerResult with
 | 
					            let random = Random(System.Guid.NewGuid().GetHashCode())
 | 
				
			||||||
            | Some player ->
 | 
					            let results = [ random.Next(0, 3) ; random.Next(0, 3) ; random.Next(0, 3)]
 | 
				
			||||||
                let sleepTime = 1000
 | 
					 | 
				
			||||||
                let random = Random(System.Guid.NewGuid().GetHashCode())
 | 
					 | 
				
			||||||
                let results = [ random.Next(0, 3) ; random.Next(0, 3) ; random.Next(0, 3)]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let winConditions = (results.[0] = results.[1] && results.[0] = results.[2])
 | 
					            let winConditions = (results.[0] = results.[1] && results.[0] = results.[2])
 | 
				
			||||||
                                    || (results.[0] <> results.[1] && results.[1] <> results.[2] && results.[0] <> results.[2])
 | 
					                                || (results.[0] <> results.[1] && results.[1] <> results.[2] && results.[0] <> results.[2])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if winConditions then
 | 
					            if winConditions then
 | 
				
			||||||
                    do! DbService.updatePlayer { player with Bank = player.Bank + 10<GBT> }
 | 
					                do! DbService.updatePlayer { player with Bank = player.Bank + 10<GBT> }
 | 
				
			||||||
                else
 | 
					            else
 | 
				
			||||||
                    do! DbService.updatePlayer { player with Bank = max (player.Bank - 1<GBT>) 0<GBT> }
 | 
					                do! DbService.updatePlayer { player with Bank = max (player.Bank - 1<GBT>) 0<GBT> }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                do! ctx.Interaction.CreateResponseAsync(InteractionResponseType.DeferredChannelMessageWithSource)
 | 
					            do! ctx.Interaction.CreateResponseAsync(InteractionResponseType.DeferredChannelMessageWithSource)
 | 
				
			||||||
                    |> Async.AwaitTask
 | 
					                |> Async.AwaitTask
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            do! Async.Sleep sleepTime
 | 
				
			||||||
 | 
					            let builder = DiscordFollowupMessageBuilder()
 | 
				
			||||||
 | 
					            let embed = DiscordEmbedBuilder()
 | 
				
			||||||
 | 
					            embed.ImageUrl <- slots.[results.[0]]
 | 
				
			||||||
 | 
					            builder.AddEmbed(embed.Build()) |> ignore
 | 
				
			||||||
 | 
					            do! ctx.Interaction.CreateFollowupMessageAsync(builder)
 | 
				
			||||||
 | 
					                |> Async.AwaitTask
 | 
				
			||||||
 | 
					                |> Async.Ignore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            do! Async.Sleep sleepTime
 | 
				
			||||||
 | 
					            let builder = DiscordFollowupMessageBuilder()
 | 
				
			||||||
 | 
					            embed.ImageUrl <- slots.[results.[1]]
 | 
				
			||||||
 | 
					            builder.AddEmbed(embed.Build()) |> ignore
 | 
				
			||||||
 | 
					            do! ctx.Interaction.CreateFollowupMessageAsync(builder)
 | 
				
			||||||
 | 
					                |> Async.AwaitTask
 | 
				
			||||||
 | 
					                |> Async.Ignore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            do! Async.Sleep sleepTime
 | 
				
			||||||
 | 
					            let builder = DiscordFollowupMessageBuilder()
 | 
				
			||||||
 | 
					            embed.ImageUrl <- slots.[results.[2]]
 | 
				
			||||||
 | 
					            builder.AddEmbed(embed.Build()) |> ignore
 | 
				
			||||||
 | 
					            do! ctx.Interaction.CreateFollowupMessageAsync(builder)
 | 
				
			||||||
 | 
					                |> Async.AwaitTask
 | 
				
			||||||
 | 
					                |> Async.Ignore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if winConditions then
 | 
				
			||||||
                do! Async.Sleep sleepTime
 | 
					                do! Async.Sleep sleepTime
 | 
				
			||||||
                let builder = DiscordFollowupMessageBuilder()
 | 
					                let builder = DiscordFollowupMessageBuilder()
 | 
				
			||||||
                let embed = DiscordEmbedBuilder()
 | 
					                builder.Content <- "You win 10 GBT!"
 | 
				
			||||||
                embed.ImageUrl <- slots.[results.[0]]
 | 
					 | 
				
			||||||
                builder.AddEmbed(embed.Build()) |> ignore
 | 
					 | 
				
			||||||
                do! ctx.Interaction.CreateFollowupMessageAsync(builder)
 | 
					                do! ctx.Interaction.CreateFollowupMessageAsync(builder)
 | 
				
			||||||
                    |> Async.AwaitTask
 | 
					                    |> Async.AwaitTask
 | 
				
			||||||
                    |> Async.Ignore
 | 
					                    |> Async.Ignore
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
                do! Async.Sleep sleepTime
 | 
					                do! Async.Sleep sleepTime
 | 
				
			||||||
                let builder = DiscordFollowupMessageBuilder()
 | 
					                let builder = DiscordFollowupMessageBuilder()
 | 
				
			||||||
                embed.ImageUrl <- slots.[results.[1]]
 | 
					                builder.Content <- "You lose 0.5 GBT! Try your luck again!"
 | 
				
			||||||
                builder.AddEmbed(embed.Build()) |> ignore
 | 
					 | 
				
			||||||
                do! ctx.Interaction.CreateFollowupMessageAsync(builder)
 | 
					                do! ctx.Interaction.CreateFollowupMessageAsync(builder)
 | 
				
			||||||
                    |> Async.AwaitTask
 | 
					                    |> Async.AwaitTask
 | 
				
			||||||
                    |> Async.Ignore
 | 
					                    |> Async.Ignore
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                do! Async.Sleep sleepTime
 | 
					 | 
				
			||||||
                let builder = DiscordFollowupMessageBuilder()
 | 
					 | 
				
			||||||
                embed.ImageUrl <- slots.[results.[2]]
 | 
					 | 
				
			||||||
                builder.AddEmbed(embed.Build()) |> ignore
 | 
					 | 
				
			||||||
                do! ctx.Interaction.CreateFollowupMessageAsync(builder)
 | 
					 | 
				
			||||||
                    |> Async.AwaitTask
 | 
					 | 
				
			||||||
                    |> Async.Ignore
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if winConditions then
 | 
					 | 
				
			||||||
                    do! Async.Sleep sleepTime
 | 
					 | 
				
			||||||
                    let builder = DiscordFollowupMessageBuilder()
 | 
					 | 
				
			||||||
                    builder.Content <- "You win 10 GBT!"
 | 
					 | 
				
			||||||
                    do! ctx.Interaction.CreateFollowupMessageAsync(builder)
 | 
					 | 
				
			||||||
                        |> Async.AwaitTask
 | 
					 | 
				
			||||||
                        |> Async.Ignore
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    do! Async.Sleep sleepTime
 | 
					 | 
				
			||||||
                    let builder = DiscordFollowupMessageBuilder()
 | 
					 | 
				
			||||||
                    builder.Content <- "You lose 0.5 GBT! Try your luck again!"
 | 
					 | 
				
			||||||
                    do! ctx.Interaction.CreateFollowupMessageAsync(builder)
 | 
					 | 
				
			||||||
                        |> Async.AwaitTask
 | 
					 | 
				
			||||||
                        |> Async.Ignore
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            | None -> do! notYetAHackerMsg ctx
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } |> Async.StartAsTask
 | 
					 | 
				
			||||||
        :> Task
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										118
									
								
								Bot/Store.fs
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								Bot/Store.fs
									
									
									
									
									
								
							@ -8,83 +8,51 @@ open DSharpPlus.EventArgs
 | 
				
			|||||||
open DSharpPlus.SlashCommands
 | 
					open DSharpPlus.SlashCommands
 | 
				
			||||||
open Degenz
 | 
					open Degenz
 | 
				
			||||||
open Degenz.Embeds
 | 
					open Degenz.Embeds
 | 
				
			||||||
open Degenz.Shared
 | 
					open Degenz.Messaging
 | 
				
			||||||
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))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
let viewStore (ctx : InteractionContext) =
 | 
					let viewStore (ctx : InteractionContext) =
 | 
				
			||||||
    async {
 | 
					    async {
 | 
				
			||||||
        do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, Embeds.storeListing armoury)
 | 
					        do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, Embeds.storeListing Armoury.battleItems)
 | 
				
			||||||
            |> Async.AwaitTask
 | 
					            |> Async.AwaitTask
 | 
				
			||||||
    } |> Async.StartAsTask
 | 
					    } |> Async.StartAsTask
 | 
				
			||||||
      :> Task
 | 
					      :> Task
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let buyItem (ctx : InteractionContext) itemId =
 | 
					let buyItem (ctx : InteractionContext) itemType =
 | 
				
			||||||
    async {
 | 
					    Game.executePlayerAction ctx (fun player -> async {
 | 
				
			||||||
        let! playerResult = DbService.tryFindPlayer ctx.Member.Id
 | 
					        let embed = DiscordEmbedBuilder()
 | 
				
			||||||
        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 constructItemButtons playerInfo itemType (items : 'a array) =
 | 
					//        embed.Fields
 | 
				
			||||||
    items
 | 
					
 | 
				
			||||||
    |> Seq.map (fun item -> DiscordButtonComponent(ButtonStyle.Primary, $"{playerInfo}-{itemType}-{item}", $"{item}"))
 | 
					        do! ctx.CreateResponseAsync(embed, true)
 | 
				
			||||||
 | 
					            |> Async.AwaitTask
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let sell (ctx : InteractionContext) =
 | 
					let sell (ctx : InteractionContext) =
 | 
				
			||||||
    async {
 | 
					    Game.executePlayerAction ctx (fun player -> async {
 | 
				
			||||||
        let! playerResult = DbService.tryFindPlayer ctx.Member.Id
 | 
					        let hasInventoryToSell = Array.length player.Arsenal > 0
 | 
				
			||||||
        match playerResult with
 | 
					        if hasInventoryToSell then
 | 
				
			||||||
        | Some player ->
 | 
					            let builder = DiscordInteractionResponseBuilder()
 | 
				
			||||||
            let hasInventoryToSell = Array.length player.Arsenal > 0
 | 
					            builder.AddEmbed (constructEmbed "Pick the item you wish to sell.") |> ignore
 | 
				
			||||||
            if hasInventoryToSell then
 | 
					 | 
				
			||||||
                let builder = DiscordInteractionResponseBuilder()
 | 
					 | 
				
			||||||
                builder.AddEmbed (constructEmbed "Pick the item you wish to sell.") |> ignore
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Array.chunkBySize 5 player.Arsenal
 | 
					            Array.chunkBySize 5 player.Arsenal
 | 
				
			||||||
                |> Array.iter
 | 
					            |> Array.iter
 | 
				
			||||||
                    (fun wps ->
 | 
					                (fun wps ->
 | 
				
			||||||
                        wps
 | 
					                    wps
 | 
				
			||||||
                        |> Array.map (fun w -> DiscordButtonComponent(ButtonStyle.Primary, $"{w.Type}-{w.Id}", $"{w.Name}"))
 | 
					                    |> Array.map (fun w -> DiscordButtonComponent(ButtonStyle.Primary, $"{w.Type}-{w.Id}", $"{w.Name}"))
 | 
				
			||||||
                        |> Seq.cast<DiscordComponent>
 | 
					                    |> Seq.cast<DiscordComponent>
 | 
				
			||||||
                        |> builder.AddComponents
 | 
					                    |> builder.AddComponents
 | 
				
			||||||
                        |> ignore)
 | 
					                    |> ignore)
 | 
				
			||||||
                builder.AsEphemeral true |> ignore
 | 
					            builder.AsEphemeral true |> ignore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
 | 
					            do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
 | 
				
			||||||
                    |> Async.AwaitTask
 | 
					                |> Async.AwaitTask
 | 
				
			||||||
            else
 | 
					        else
 | 
				
			||||||
                do! createSimpleResponseAsync "You currently have no inventory to sell" ctx
 | 
					            do! sendSimpleResponse ctx "You currently have no inventory to sell"
 | 
				
			||||||
        | None -> do! notYetAHackerMsg ctx
 | 
					    })
 | 
				
			||||||
        return ()
 | 
					 | 
				
			||||||
    } |> Async.StartAsTask
 | 
					 | 
				
			||||||
      :> Task
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let updateArsenal player salePrice updatedArsenal = { player with Bank = player.Bank + salePrice ; Arsenal = updatedArsenal }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
let sellItem (event : ComponentInteractionCreateEventArgs) player itemId =
 | 
					let sellItem (event : ComponentInteractionCreateEventArgs) player itemId =
 | 
				
			||||||
    async {
 | 
					    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)}
 | 
					        let updatedPlayer = { player with Bank = player.Bank + item.Cost ; Arsenal = player.Arsenal |> Array.filter (fun w -> w.Id <> itemId)}
 | 
				
			||||||
        do! DbService.updatePlayer updatedPlayer
 | 
					        do! DbService.updatePlayer updatedPlayer
 | 
				
			||||||
        let builder = DiscordInteractionResponseBuilder()
 | 
					        let builder = DiscordInteractionResponseBuilder()
 | 
				
			||||||
@ -94,6 +62,22 @@ let sellItem (event : ComponentInteractionCreateEventArgs) player itemId =
 | 
				
			|||||||
            |> Async.AwaitTask
 | 
					            |> 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) =
 | 
					let handleSellButtonEvents (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
 | 
				
			||||||
    async {
 | 
					    async {
 | 
				
			||||||
        let! playerResult = DbService.tryFindPlayer event.User.Id
 | 
					        let! playerResult = DbService.tryFindPlayer event.User.Id
 | 
				
			||||||
@ -112,17 +96,15 @@ let handleSellButtonEvents (_ : DiscordClient) (event : ComponentInteractionCrea
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type Store() =
 | 
					type Store() =
 | 
				
			||||||
    inherit ApplicationCommandModule ()
 | 
					    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")>]
 | 
					    [<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) =
 | 
					    member _.BuyHack (ctx : InteractionContext) = buyItem ctx Hack
 | 
				
			||||||
        buyItem ctx (int hackId)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [<SlashCommand("buy-shield", "Purchase a hack shield so you can protect your GoodBoyTokenz")>]
 | 
					    [<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) =
 | 
					    member this.BuyShield (ctx : InteractionContext) = buyItem ctx Shield
 | 
				
			||||||
        buyItem ctx (int shieldId)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [<SlashCommand("sell", "Sell an item in your inventory for GoodBoyTokenz")>]
 | 
					    [<SlashCommand("sell", "Sell an item in your inventory for GoodBoyTokenz")>]
 | 
				
			||||||
    member this.SellItem (ctx : InteractionContext) = sell ctx
 | 
					    member this.SellItem (ctx : InteractionContext) = sell ctx
 | 
				
			||||||
 | 
				
			|||||||
@ -5,11 +5,11 @@ open DSharpPlus
 | 
				
			|||||||
open DSharpPlus.Entities
 | 
					open DSharpPlus.Entities
 | 
				
			||||||
open DSharpPlus.EventArgs
 | 
					open DSharpPlus.EventArgs
 | 
				
			||||||
open DSharpPlus.SlashCommands
 | 
					open DSharpPlus.SlashCommands
 | 
				
			||||||
open Degenz.Shared
 | 
					open Degenz.Types
 | 
				
			||||||
open Degenz.Store
 | 
					open Degenz.Messaging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let defaultHack = armoury |> Array.find (fun i -> i.Id = int HackId.Virus)
 | 
					let defaultHack = Armoury.battleItems |> Array.find (fun i -> i.Id = int HackId.Virus)
 | 
				
			||||||
let defaultShield = armoury |> Array.find (fun i -> i.Id = int ShieldId.Firewall)
 | 
					let defaultShield = Armoury.battleItems |> Array.find (fun i -> i.Id = int ShieldId.Firewall)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let sendInitialEmbed (client : DiscordClient)  =
 | 
					let sendInitialEmbed (client : DiscordClient)  =
 | 
				
			||||||
    async {
 | 
					    async {
 | 
				
			||||||
@ -41,10 +41,10 @@ let handleTrainerStep1 (event : ComponentInteractionCreateEventArgs) =
 | 
				
			|||||||
            |> Async.AwaitTask
 | 
					            |> Async.AwaitTask
 | 
				
			||||||
        match maybePlayer with
 | 
					        match maybePlayer with
 | 
				
			||||||
        | Some _ ->
 | 
					        | Some _ ->
 | 
				
			||||||
            do! Message.sendFollowUpMessageWithButton event step1Msg
 | 
					            do! sendFollowUpMessageWithButton event step1Msg
 | 
				
			||||||
        | None ->
 | 
					        | None ->
 | 
				
			||||||
            let msg = "Looks like an error occurred, you're not a registered degenerate. Please contact a moderator."
 | 
					            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) =
 | 
					let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) =
 | 
				
			||||||
@ -53,19 +53,19 @@ let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) =
 | 
				
			|||||||
        match result with
 | 
					        match result with
 | 
				
			||||||
        | Some player ->
 | 
					        | Some player ->
 | 
				
			||||||
            let weaponName = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name
 | 
					            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 =
 | 
					            let shieldMessage =
 | 
				
			||||||
                if Player.shields player |> Array.isEmpty
 | 
					                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"
 | 
					                    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"
 | 
					                    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. "
 | 
					                    ($"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."
 | 
					                     + $"{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}'.")
 | 
					                     + $"\n\nRun the `/defend` command now and then select '{weaponName}'.")
 | 
				
			||||||
        | None ->
 | 
					        | 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) =
 | 
					let defend (ctx : InteractionContext) =
 | 
				
			||||||
@ -100,7 +100,7 @@ let handleDefenseMsg = {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let handleDefense (event : ComponentInteractionCreateEventArgs) =
 | 
					let handleDefense (event : ComponentInteractionCreateEventArgs) =
 | 
				
			||||||
    let sendMessage' = Message.sendFollowUpMessage event
 | 
					    let sendMessage' = sendFollowUpMessage event
 | 
				
			||||||
    async {
 | 
					    async {
 | 
				
			||||||
        do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
 | 
					        do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
 | 
				
			||||||
            |> Async.AwaitTask
 | 
					            |> Async.AwaitTask
 | 
				
			||||||
@ -116,7 +116,7 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
 | 
				
			|||||||
            do! Async.Sleep 4000
 | 
					            do! Async.Sleep 4000
 | 
				
			||||||
            do! sendMessage' $"Hacking attempt failed! {player.Name} defended hack from Degenz-Trainer and took {prize} from them! "
 | 
					            do! sendMessage' $"Hacking attempt failed! {player.Name} defended hack from Degenz-Trainer and took {prize} from them! "
 | 
				
			||||||
            do! Async.Sleep 3000
 | 
					            do! Async.Sleep 3000
 | 
				
			||||||
            do! Message.sendFollowUpMessageWithButton event handleDefenseMsg
 | 
					            do! sendFollowUpMessageWithButton event handleDefenseMsg
 | 
				
			||||||
        | None ->
 | 
					        | None ->
 | 
				
			||||||
            do! sendMessage' $"Something went wrong, please contact a moderator"
 | 
					            do! sendMessage' $"Something went wrong, please contact a moderator"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -127,19 +127,19 @@ let handleTrainerStep4 (event : ComponentInteractionCreateEventArgs) =
 | 
				
			|||||||
        match result with
 | 
					        match result with
 | 
				
			||||||
        | Some player ->
 | 
					        | Some player ->
 | 
				
			||||||
            let weaponName = Player.hacks player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name
 | 
					            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 =
 | 
					            let hackMessage =
 | 
				
			||||||
                if Player.shields player |> Array.isEmpty
 | 
					                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"
 | 
					                    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"
 | 
					                    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, "
 | 
					                  ($"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."
 | 
					                  + $" 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.")
 | 
					                  + $"\n\nRun the `/hack` command now and pick me as your target, then click on the '{weaponName}' button.")
 | 
				
			||||||
        | None ->
 | 
					        | 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) =
 | 
					let attack (ctx : InteractionContext) (target : DiscordUser) =
 | 
				
			||||||
@ -184,7 +184,7 @@ let handleAttackMsg = {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let handleAttack (event : ComponentInteractionCreateEventArgs) =
 | 
					let handleAttack (event : ComponentInteractionCreateEventArgs) =
 | 
				
			||||||
    let sendMessage' = Message.sendFollowUpMessage event
 | 
					    let sendMessage' = sendFollowUpMessage event
 | 
				
			||||||
    async {
 | 
					    async {
 | 
				
			||||||
        do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
 | 
					        do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
 | 
				
			||||||
            |> Async.AwaitTask
 | 
					            |> 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. "
 | 
					            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.")
 | 
					                              + "Hacks take time to recover so check back in later once you've used all your hacks.")
 | 
				
			||||||
            do! Async.Sleep 7000
 | 
					            do! Async.Sleep 7000
 | 
				
			||||||
            do! Message.sendFollowUpMessageWithButton event handleAttackMsg
 | 
					            do! sendFollowUpMessageWithButton event handleAttackMsg
 | 
				
			||||||
        | None ->
 | 
					        | None ->
 | 
				
			||||||
            do! sendMessage' $"Something went wrong, please contact a moderator"
 | 
					            do! sendMessage' $"Something went wrong, please contact a moderator"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -214,7 +214,7 @@ let handleTrainerStep6 (event : ComponentInteractionCreateEventArgs) =
 | 
				
			|||||||
        let builder = DiscordFollowupMessageBuilder()
 | 
					        let builder = DiscordFollowupMessageBuilder()
 | 
				
			||||||
        builder.IsEphemeral <- true
 | 
					        builder.IsEphemeral <- true
 | 
				
			||||||
        builder.Content <- "Get out of here!"
 | 
					        builder.Content <- "Get out of here!"
 | 
				
			||||||
        do! Message.updateMessageWithGreyedOutButtons event handleAttackMsg
 | 
					        do! updateMessageWithGreyedOutButtons event handleAttackMsg
 | 
				
			||||||
        do! event.Interaction.CreateFollowupMessageAsync(builder)
 | 
					        do! event.Interaction.CreateFollowupMessageAsync(builder)
 | 
				
			||||||
            |> Async.AwaitTask
 | 
					            |> Async.AwaitTask
 | 
				
			||||||
            |> Async.Ignore
 | 
					            |> Async.Ignore
 | 
				
			||||||
@ -230,6 +230,6 @@ let handleButtonEvent (event : ComponentInteractionCreateEventArgs) =
 | 
				
			|||||||
        | 4 -> do! handleTrainerStep4 event
 | 
					        | 4 -> do! handleTrainerStep4 event
 | 
				
			||||||
        | 5 -> do! handleAttack event
 | 
					        | 5 -> do! handleAttack event
 | 
				
			||||||
        | 6 -> do! handleTrainerStep6 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
 | 
				
			||||||
open System.Collections.Generic
 | 
					open System.Collections.Generic
 | 
				
			||||||
open Degenz.Shared
 | 
					open System.Threading.Tasks
 | 
				
			||||||
 | 
					open Degenz.Types
 | 
				
			||||||
open MongoDB.Bson
 | 
					open MongoDB.Bson
 | 
				
			||||||
open MongoDB.Bson.Serialization
 | 
					open MongoDB.Bson.Serialization
 | 
				
			||||||
open MongoDB.Driver
 | 
					open MongoDB.Driver
 | 
				
			||||||
@ -62,7 +63,7 @@ let private playerMap (player : PlayerData) = {
 | 
				
			|||||||
let private mapBack (player : PlayerEntry) : PlayerData = {
 | 
					let private mapBack (player : PlayerEntry) : PlayerData = {
 | 
				
			||||||
    DiscordId = player.DiscordId
 | 
					    DiscordId = player.DiscordId
 | 
				
			||||||
    Name = player.Name
 | 
					    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 =
 | 
					    Actions =
 | 
				
			||||||
        let atks = player.Attacks |> Array.map attackToAction
 | 
					        let atks = player.Attacks |> Array.map attackToAction
 | 
				
			||||||
        let dfns = player.Defenses |> Array.map defenseToAction
 | 
					        let dfns = player.Defenses |> Array.map defenseToAction
 | 
				
			||||||
@ -113,6 +114,7 @@ let updatePlayer (player : PlayerData) =
 | 
				
			|||||||
        return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
 | 
					        return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//let getTopPlayers amount =
 | 
					//let getTopPlayers amount =
 | 
				
			||||||
//    async {
 | 
					//    async {
 | 
				
			||||||
//        return! players.FindAsync()
 | 
					//        return! players.FindAsync()
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										185
									
								
								Shared/Shared.fs
									
									
									
									
									
								
							
							
						
						
									
										185
									
								
								Shared/Shared.fs
									
									
									
									
									
								
							@ -1,4 +1,4 @@
 | 
				
			|||||||
module Degenz.Shared
 | 
					namespace Degenz
 | 
				
			||||||
 | 
					
 | 
				
			||||||
open System
 | 
					open System
 | 
				
			||||||
open DSharpPlus
 | 
					open DSharpPlus
 | 
				
			||||||
@ -7,71 +7,82 @@ open DSharpPlus.EventArgs
 | 
				
			|||||||
open DSharpPlus.SlashCommands
 | 
					open DSharpPlus.SlashCommands
 | 
				
			||||||
open Newtonsoft.Json
 | 
					open Newtonsoft.Json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[<Measure>]
 | 
					[<Microsoft.FSharp.Core.AutoOpen>]
 | 
				
			||||||
type mins
 | 
					module Types =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[<Measure>]
 | 
					    [<Measure>]
 | 
				
			||||||
type GBT
 | 
					    type mins
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BattleClass =
 | 
					    [<Measure>]
 | 
				
			||||||
    | Network
 | 
					    type GBT
 | 
				
			||||||
    | Exploit
 | 
					 | 
				
			||||||
    | Penetration
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type HackId =
 | 
					    type BattleClass =
 | 
				
			||||||
    | Virus = 0
 | 
					        | Network
 | 
				
			||||||
    | RemoteAccess = 1
 | 
					        | Exploit
 | 
				
			||||||
    | Worm = 2
 | 
					        | Penetration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ShieldId =
 | 
					    type HackId =
 | 
				
			||||||
    | Firewall = 6
 | 
					        | Virus = 0
 | 
				
			||||||
    | Encryption = 7
 | 
					        | RemoteAccess = 1
 | 
				
			||||||
    | Cypher = 8
 | 
					        | Worm = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ItemType =
 | 
					    type ShieldId =
 | 
				
			||||||
    | Hack
 | 
					        | Firewall = 6
 | 
				
			||||||
    | Shield
 | 
					        | Encryption = 7
 | 
				
			||||||
 | 
					        | Cypher = 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BattleItem = {
 | 
					    type ItemType =
 | 
				
			||||||
    Id : int
 | 
					        | Hack
 | 
				
			||||||
    Name : string
 | 
					        | Shield
 | 
				
			||||||
    Cost : int<GBT>
 | 
					 | 
				
			||||||
    Type : ItemType
 | 
					 | 
				
			||||||
    Class : BattleClass
 | 
					 | 
				
			||||||
    Power : int
 | 
					 | 
				
			||||||
    Cooldown : int<mins>
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type HackResult =
 | 
					    type BattleItem = {
 | 
				
			||||||
    | Strong
 | 
					        Id : int
 | 
				
			||||||
    | Weak
 | 
					        Name : string
 | 
				
			||||||
 | 
					        Cost : int<GBT>
 | 
				
			||||||
 | 
					        Type : ItemType
 | 
				
			||||||
 | 
					        Class : BattleClass
 | 
				
			||||||
 | 
					        Power : int
 | 
				
			||||||
 | 
					        Cooldown : int<mins>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[<CLIMutable>]
 | 
					    type HackResult =
 | 
				
			||||||
type DiscordPlayer = { Id: uint64; Name: string }
 | 
					        | Strong
 | 
				
			||||||
 | 
					        | Weak
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[<CLIMutable>]
 | 
					    [<CLIMutable>]
 | 
				
			||||||
type AttackResult = {
 | 
					    type DiscordPlayer = { Id: uint64; Name: string }
 | 
				
			||||||
    Result : bool
 | 
					 | 
				
			||||||
    Target : DiscordPlayer
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ActionType =
 | 
					    [<CLIMutable>]
 | 
				
			||||||
    | Attack of AttackResult
 | 
					    type AttackResult = {
 | 
				
			||||||
    | Defense
 | 
					        Result : bool
 | 
				
			||||||
 | 
					        Target : DiscordPlayer
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[<CLIMutable>]
 | 
					    type ActionType =
 | 
				
			||||||
type Action =
 | 
					        | Attack of AttackResult
 | 
				
			||||||
    { ActionId : int
 | 
					        | Defense
 | 
				
			||||||
      Type : ActionType
 | 
					 | 
				
			||||||
      Timestamp : DateTime }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
[<CLIMutable>]
 | 
					    [<CLIMutable>]
 | 
				
			||||||
type PlayerData =
 | 
					    type Action =
 | 
				
			||||||
    { DiscordId : uint64
 | 
					        { ActionId : int
 | 
				
			||||||
      Name : string
 | 
					          Type : ActionType
 | 
				
			||||||
      Arsenal : BattleItem array
 | 
					          Timestamp : DateTime }
 | 
				
			||||||
      Actions : Action array
 | 
					
 | 
				
			||||||
      Bank : int<GBT> }
 | 
					    [<CLIMutable>]
 | 
				
			||||||
 | 
					    type PlayerData =
 | 
				
			||||||
 | 
					        { DiscordId : uint64
 | 
				
			||||||
 | 
					          Name : string
 | 
				
			||||||
 | 
					          Arsenal : BattleItem array
 | 
				
			||||||
 | 
					          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 =
 | 
					module Player =
 | 
				
			||||||
    let hacks player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Hack)
 | 
					    let hacks player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Hack)
 | 
				
			||||||
@ -81,48 +92,44 @@ module Player =
 | 
				
			|||||||
        |> Array.choose (fun act -> match act.Type with Attack ar -> Some (act,ar.Target,ar.Result) | Defense -> None)
 | 
					        |> 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 defenses player = player.Actions |> Array.filter (fun act -> match act.Type with Defense _ -> true | _ -> false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let getAttacksFlat actions = actions |> Array.choose (fun act -> match act.Type with Attack ar -> Some (act,ar.Target,ar.Result) | Defense -> None)
 | 
					    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 createSimpleResponseAsync msg (ctx: InteractionContext) =
 | 
					    let modifyBank player amount = { player with Bank = max (player.Bank + amount) 0<GBT> }
 | 
				
			||||||
    async {
 | 
					 | 
				
			||||||
        let builder = DiscordInteractionResponseBuilder()
 | 
					 | 
				
			||||||
        builder.Content <- msg
 | 
					 | 
				
			||||||
        builder.AsEphemeral true |> ignore
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        do!
 | 
					    let getAttacksFlat actions = actions |> Array.choose (fun act -> match act.Type with Attack ar -> Some (act,ar.Target,ar.Result) | Defense -> None)
 | 
				
			||||||
            ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
 | 
					
 | 
				
			||||||
            |> Async.AwaitTask
 | 
					
 | 
				
			||||||
 | 
					module Messaging =
 | 
				
			||||||
 | 
					    type InteractiveMessage = {
 | 
				
			||||||
 | 
					        ButtonId : string
 | 
				
			||||||
 | 
					        ButtonText : string
 | 
				
			||||||
 | 
					        Message : string
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let notYetAHackerMsg =
 | 
					    let statusFormat p =
 | 
				
			||||||
    createSimpleResponseAsync "You are currently not a hacker, first use the /redpill command to become one"
 | 
					        $"Hacks: {Player.hacks p |> Array.toList}
 | 
				
			||||||
 | 
					    Shields: {Player.shields p |> Array.toList}
 | 
				
			||||||
 | 
					    Hack Attacks: {Player.attacks p |> Array.toList}
 | 
				
			||||||
 | 
					    Active Defenses: {Player.defenses p |> Array.toList}
 | 
				
			||||||
 | 
					    Bank: {p.Bank}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let hackDescription = ""
 | 
					    let constructButtons (actionType: string) (playerInfo: string) (weapons: BattleItem array) =
 | 
				
			||||||
 | 
					        weapons
 | 
				
			||||||
 | 
					        |> Array.map (fun w -> DiscordButtonComponent(ButtonStyle.Success, $"{actionType}-{w.Id}-{playerInfo}", $"{w.Name}"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let statusFormat p =
 | 
					    let sendSimpleResponse (ctx: InteractionContext) msg =
 | 
				
			||||||
    $"Hacks: {Player.hacks p |> Array.toList}
 | 
					        async {
 | 
				
			||||||
Shields: {Player.shields p |> Array.toList}
 | 
					            let builder = DiscordInteractionResponseBuilder()
 | 
				
			||||||
Hack Attacks: {Player.attacks p |> Array.toList}
 | 
					            builder.Content <- msg
 | 
				
			||||||
Active Defenses: {Player.defenses p |> Array.toList}
 | 
					            builder.AsEphemeral true |> ignore
 | 
				
			||||||
Bank: {p.Bank}"
 | 
					            do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
 | 
				
			||||||
 | 
					                |> Async.AwaitTask
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let constructButtons (actionType: string) (playerInfo: string) (weapons: BattleItem array) =
 | 
					 | 
				
			||||||
    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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module Message =
 | 
					 | 
				
			||||||
    let sendFollowUpMessage (event : ComponentInteractionCreateEventArgs) msg =
 | 
					    let sendFollowUpMessage (event : ComponentInteractionCreateEventArgs) msg =
 | 
				
			||||||
        async {
 | 
					        async {
 | 
				
			||||||
            let builder = DiscordFollowupMessageBuilder()
 | 
					            let builder = DiscordFollowupMessageBuilder()
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user