Fixing some trainer bugs, mapping value cause Mongo hates F#
This commit is contained in:
parent
7c8a460d5b
commit
7b48ff0a9b
@ -26,7 +26,6 @@ for conf in configs do
|
||||
conf.TokenType <- TokenType.Bot
|
||||
conf.Intents <- DiscordIntents.All
|
||||
|
||||
|
||||
let guild = GuildEnvironment.guildId
|
||||
|
||||
playerInteractionsConfig.Token <- GuildEnvironment.tokenPlayerInteractions
|
||||
|
@ -84,7 +84,7 @@ let responseSuccessfulHackTrainer defenderName (hack : BattleItem) prize =
|
||||
embed.ImageUrl <- getHackGif (enum<HackId>(hack.Id))
|
||||
|
||||
DiscordFollowupMessageBuilder()
|
||||
.WithContent($"Successfully hacked {defenderName} using {hack}! You just won {prize} GoodBoyTokenz!")
|
||||
.WithContent($"Successfully hacked {defenderName} using {hack.Name}! You just won {prize} GoodBoyTokenz!")
|
||||
.AddEmbed(embed.Build())
|
||||
.AsEphemeral(true)
|
||||
|
||||
|
@ -8,6 +8,7 @@ open DSharpPlus.EventArgs
|
||||
open DSharpPlus.SlashCommands
|
||||
open Degenz
|
||||
open Degenz.Shared
|
||||
open Degenz.Store
|
||||
|
||||
let getTimeTillCooldownFinishes (timespan : TimeSpan) timestamp =
|
||||
let timeRemaining = timespan - (DateTime.UtcNow - timestamp)
|
||||
@ -42,7 +43,7 @@ let checkIfHackHasCooldown hackId attacker =
|
||||
|> Array.tryFind (fun a -> a.ActionId = hackId)
|
||||
|> function
|
||||
| Some a -> a.Timestamp
|
||||
| None -> DateTime.MinValue
|
||||
| None -> DateTime.MinValue;
|
||||
if DateTime.UtcNow - mostRecentHackAttack > TimeSpan.FromMinutes(5) then
|
||||
Ok attacker
|
||||
else
|
||||
@ -56,7 +57,7 @@ let checkIfInventoryIsEmpty attacker =
|
||||
| _ -> Ok attacker
|
||||
|
||||
let calculateDamage (hack : BattleItem) (shield : BattleItem) =
|
||||
if hack.Power > shield.Power
|
||||
if hack.Class = shield.Class
|
||||
then Strong
|
||||
else Weak
|
||||
|
||||
@ -71,7 +72,7 @@ let updateCombatants attacker defender hack prize =
|
||||
let updatePlayer amount attack p =
|
||||
{ p with Actions = Array.append [| attack |] p.Actions ; Bank = max (p.Bank + amount) 0<GBT> }
|
||||
let target = { Id = defender.DiscordId ; Name = defender.Name }
|
||||
let attack = { ActionId = int hack ; Type = Attack ( target , 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 <| modifyPlayerBank defender -prize ]
|
||||
@ -179,7 +180,7 @@ let defend (ctx : InteractionContext) =
|
||||
let! player = DbService.tryFindPlayer ctx.Member.Id
|
||||
match player with
|
||||
| Some player ->
|
||||
if Player.defenses player |> Array.length > 0 then
|
||||
if Player.shields player |> Array.length > 0 then
|
||||
let embed = Embeds.pickDefense "Defend" player
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed)
|
||||
|> Async.AwaitTask
|
||||
|
@ -32,7 +32,7 @@
|
||||
"Case": "Hack"
|
||||
},
|
||||
"Class": {
|
||||
"Case": "Network"
|
||||
"Case": "Exploit"
|
||||
},
|
||||
"Cost": 100,
|
||||
"Power": 50,
|
||||
@ -45,7 +45,7 @@
|
||||
"Case": "Hack"
|
||||
},
|
||||
"Class": {
|
||||
"Case": "Network"
|
||||
"Case": "Exploit"
|
||||
},
|
||||
"Cost": 100,
|
||||
"Power": 50,
|
||||
@ -58,7 +58,7 @@
|
||||
"Case": "Hack"
|
||||
},
|
||||
"Class": {
|
||||
"Case": "Network"
|
||||
"Case": "Penetration"
|
||||
},
|
||||
"Cost": 100,
|
||||
"Power": 50,
|
||||
@ -71,7 +71,7 @@
|
||||
"Case": "Hack"
|
||||
},
|
||||
"Class": {
|
||||
"Case": "Network"
|
||||
"Case": "Penetration"
|
||||
},
|
||||
"Cost": 100,
|
||||
"Power": 50,
|
||||
@ -110,7 +110,7 @@
|
||||
"Case": "Shield"
|
||||
},
|
||||
"Class": {
|
||||
"Case": "Network"
|
||||
"Case": "Exploit"
|
||||
},
|
||||
"Cost": 100,
|
||||
"Power": 50,
|
||||
@ -123,7 +123,7 @@
|
||||
"Case": "Shield"
|
||||
},
|
||||
"Class": {
|
||||
"Case": "Network"
|
||||
"Case": "Penetration"
|
||||
},
|
||||
"Cost": 100,
|
||||
"Power": 50,
|
||||
@ -136,7 +136,7 @@
|
||||
"Case": "Shield"
|
||||
},
|
||||
"Class": {
|
||||
"Case": "Network"
|
||||
"Case": "Penetration"
|
||||
},
|
||||
"Cost": 100,
|
||||
"Power": 50,
|
||||
@ -149,7 +149,7 @@
|
||||
"Case": "Shield"
|
||||
},
|
||||
"Class": {
|
||||
"Case": "Network"
|
||||
"Case": "Exploit"
|
||||
},
|
||||
"Cost": 100,
|
||||
"Power": 50,
|
||||
|
@ -1,77 +1,48 @@
|
||||
module Degenz.PlayerInteractions
|
||||
|
||||
open System
|
||||
open System.Threading.Tasks
|
||||
open AsciiTableFormatter
|
||||
open DSharpPlus.Entities
|
||||
open DSharpPlus
|
||||
open DSharpPlus.SlashCommands
|
||||
open Degenz
|
||||
open Degenz.Store
|
||||
open Degenz.Shared
|
||||
|
||||
module Commands =
|
||||
// let newPlayer nickname (membr : uint64) =
|
||||
// let h1 = [| Weapon.Virus ; Weapon.Ransom |]
|
||||
// let h2 = [| Weapon.DDos ; Weapon.Worm |]
|
||||
// let h3 = [| Weapon.Crack ; Weapon.Injection |]
|
||||
// let d1 = [| Shield.Firewall ; Shield.PortScan |]
|
||||
// let d2 = [| Shield.Encryption ; Shield.Cypher |]
|
||||
// let d3 = [| Shield.Hardening ; Shield.Sanitation |]
|
||||
let newPlayer nickname (membr : uint64) =
|
||||
|
||||
// let rand = System.Random(System.Guid.NewGuid().GetHashCode())
|
||||
// let getRandom (actions : 'a array) = actions.[rand.Next(0, max 0 (actions.Length - 1))]
|
||||
//
|
||||
// let weapons = [| getRandom hackInventory |]
|
||||
// let shields = [| getRandom shieldInventory |]
|
||||
//
|
||||
// { DiscordId = membr
|
||||
// Name = nickname
|
||||
// Weapons = weapons
|
||||
// Shields = shields
|
||||
// Attacks = [||]
|
||||
// Defenses = [||]
|
||||
// Bank = 15 }
|
||||
let rand = System.Random(System.Guid.NewGuid().GetHashCode())
|
||||
let randHack = rand.Next(0, 3)
|
||||
let randShield = rand.Next(3, 6)
|
||||
let hack = armoury |> Array.find (fun i -> i.Id = randHack)
|
||||
let shield = armoury |> Array.find (fun i -> i.Id = randShield)
|
||||
|
||||
// let addHackerRole (ctx : InteractionContext) =
|
||||
// async {
|
||||
// let! player = DbService.tryFindPlayer ctx.Member.Id
|
||||
// let! newPlayer =
|
||||
// match player with
|
||||
// | Some _ -> async.Return false
|
||||
// | None ->
|
||||
// async {
|
||||
// do! newPlayer ctx.Member.DisplayName ctx.Member.Id
|
||||
// |> DbService.insertNewPlayer
|
||||
//
|
||||
// for role in ctx.Guild.Roles do
|
||||
// if role.Value.Name = "Hacker" then
|
||||
// do! ctx.Member.GrantRoleAsync(role.Value)
|
||||
// |> Async.AwaitTask
|
||||
// return true
|
||||
// }
|
||||
// if newPlayer then
|
||||
// do! ctx.CreateResponseAsync("You are now an elite haxxor", true)
|
||||
// |> Async.AwaitTask
|
||||
// else
|
||||
// do! ctx.CreateResponseAsync("Already registered as an elite haxxor", true)
|
||||
// |> Async.AwaitTask
|
||||
//
|
||||
// } |> Async.StartAsTask
|
||||
// :> Task
|
||||
{ DiscordId = membr
|
||||
Name = nickname
|
||||
Arsenal = [| hack ; shield |]
|
||||
Actions = [||]
|
||||
Bank = 100<GBT> }
|
||||
|
||||
// let removeHackerRole (ctx : InteractionContext) =
|
||||
// async {
|
||||
// for role in ctx.Member.Roles do
|
||||
// if role.Name = "Hacker" then
|
||||
// do! ctx.Member.RevokeRoleAsync(role)
|
||||
// |> Async.AwaitTask
|
||||
let addHackerRole (ctx : InteractionContext) =
|
||||
async {
|
||||
let! player = DbService.tryFindPlayer ctx.Member.Id
|
||||
let! newPlayer =
|
||||
match player with
|
||||
| Some _ -> async.Return false
|
||||
| None ->
|
||||
async {
|
||||
do! newPlayer ctx.Member.DisplayName ctx.Member.Id
|
||||
|> DbService.insertNewPlayer
|
||||
return true
|
||||
}
|
||||
if newPlayer then
|
||||
do! ctx.CreateResponseAsync("You are now an elite haxxor", true)
|
||||
|> Async.AwaitTask
|
||||
else
|
||||
do! ctx.CreateResponseAsync("Already registered as an elite haxxor", true)
|
||||
|> Async.AwaitTask
|
||||
|
||||
// do! DbService.removePlayer ctx.Member.Id
|
||||
|
||||
// do! ctx.CreateResponseAsync("You are now lame", true)
|
||||
// |> Async.AwaitTask
|
||||
// } |> Async.StartAsTask
|
||||
// :> Task
|
||||
} |> Async.StartAsTask
|
||||
:> Task
|
||||
|
||||
[<CLIMutable>]
|
||||
type LeaderboardEntry = {
|
||||
@ -103,18 +74,17 @@ module Commands =
|
||||
|
||||
let status (ctx : InteractionContext) =
|
||||
async {
|
||||
let! player = DbService.tryFindPlayer ctx.Member.Id
|
||||
match player with
|
||||
| Some p ->
|
||||
// let updatedAttacks = p.Attacks |> removeExpiredActions (TimeSpan.FromHours(24)) (fun (atk : Attack) -> atk.Timestamp)
|
||||
// let updatedDefenses = p.Defenses |> removeExpiredActions (TimeSpan.FromHours(6)) (fun (p : Defense) -> p.Timestamp)
|
||||
// let updatedPlayer = { p with Attacks = updatedAttacks ; Defenses = updatedDefenses }
|
||||
// do! DbService.updatePlayer updatedPlayer
|
||||
let! maybePlayer = DbService.tryFindPlayer ctx.Member.Id
|
||||
match maybePlayer with
|
||||
| Some player ->
|
||||
let updatedActions = removeExpiredActions player.Actions
|
||||
let updatedPlayer = { player with Actions = updatedActions }
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.IsEphemeral <- true
|
||||
// builder.Content <- statusFormat updatedPlayer
|
||||
builder.Content <- statusFormat updatedPlayer
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||
|> Async.AwaitTask
|
||||
do! DbService.updatePlayer updatedPlayer
|
||||
| None -> do! notYetAHackerMsg ctx
|
||||
} |> Async.StartAsTask
|
||||
:> Task
|
||||
@ -122,11 +92,8 @@ module Commands =
|
||||
type PlayerInteractions() =
|
||||
inherit ApplicationCommandModule ()
|
||||
|
||||
// [<SlashCommand("redpill", "Take the redpill and become a hacker")>]
|
||||
// member _.AddHackerRole (ctx : InteractionContext) = Commands.addHackerRole ctx
|
||||
|
||||
// [<SlashCommand("bluepill", "Take the bluepill and become lame")>]
|
||||
// member _.RemoveHackerRole (ctx : InteractionContext) = Commands.removeHackerRole ctx
|
||||
[<SlashCommand("redpill", "Take the redpill and become a hacker")>]
|
||||
member _.AddHackerRole (ctx : InteractionContext) = Commands.addHackerRole ctx
|
||||
|
||||
[<SlashCommand("status", "Get your current status like bank account, and active hacks and defenses")>]
|
||||
member this.Status (ctx : InteractionContext) = Commands.status ctx
|
||||
|
10
Bot/Store.fs
10
Bot/Store.fs
@ -1,5 +1,6 @@
|
||||
module Degenz.Store
|
||||
|
||||
open System
|
||||
open System.Threading.Tasks
|
||||
open DSharpPlus.Entities
|
||||
open DSharpPlus
|
||||
@ -8,6 +9,15 @@ 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))
|
||||
|
||||
let viewStore (ctx : InteractionContext) =
|
||||
async {
|
||||
|
@ -6,6 +6,7 @@ open DSharpPlus.Entities
|
||||
open DSharpPlus.EventArgs
|
||||
open DSharpPlus.SlashCommands
|
||||
open Degenz.Shared
|
||||
open Degenz.Store
|
||||
|
||||
let defaultHack = armoury |> Array.find (fun i -> i.Id = int HackId.Virus)
|
||||
let defaultShield = armoury |> Array.find (fun i -> i.Id = int ShieldId.Firewall)
|
||||
@ -54,7 +55,7 @@ let handleTrainerStep2 (event : ComponentInteractionCreateEventArgs) =
|
||||
let! result = DbService.tryFindPlayer event.User.Id
|
||||
match result with
|
||||
| Some player ->
|
||||
let weaponName = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield
|
||||
let weaponName = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name
|
||||
do! Message.sendInteractionEvent event
|
||||
($"First things first, let's get your system protected. Let's enable a shield to protect you from potential hackers. "
|
||||
+ $"You currently have {weaponName} in your arsenal. To enable it and protect your system, you can use the `/defend` slash command to choose a shield."
|
||||
@ -92,11 +93,11 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
|
||||
async {
|
||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.DeferredMessageUpdate)
|
||||
|> Async.AwaitTask
|
||||
let! result = DbService.tryFindPlayer event.User.Id
|
||||
match result with
|
||||
let! maybePlayer = DbService.tryFindPlayer event.User.Id
|
||||
match maybePlayer with
|
||||
| Some player ->
|
||||
let prize = 0.223f
|
||||
let shield = player.Arsenal |> Array.tryHead |> Option.defaultValue defaultShield
|
||||
let shield = Player.shields player |> Array.tryHead |> Option.defaultValue defaultShield
|
||||
let embed = Embeds.responseCreatedShieldTrainer shield
|
||||
do! event.Interaction.CreateFollowupMessageAsync(embed) |> Async.AwaitTask |> Async.Ignore
|
||||
do! Async.Sleep 2000
|
||||
@ -116,7 +117,7 @@ let handleTrainerStep4 (event : ComponentInteractionCreateEventArgs) =
|
||||
let! result = DbService.tryFindPlayer event.User.Id
|
||||
match result with
|
||||
| Some player ->
|
||||
let weaponName = player.Arsenal |> Array.tryHead |> Option.defaultValue defaultHack
|
||||
let weaponName = Player.hacks player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name
|
||||
do! Message.sendInteractionEvent event
|
||||
($"Next why don't you try hacking me. You currently have {weaponName} equipped. 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."
|
||||
|
@ -7,6 +7,68 @@ open MongoDB.Bson
|
||||
open MongoDB.Bson.Serialization
|
||||
open MongoDB.Driver
|
||||
|
||||
[<CLIMutable>]
|
||||
type AttackAction =
|
||||
{ ActionId : int
|
||||
Result : bool
|
||||
Target : DiscordPlayer
|
||||
Timestamp : DateTime }
|
||||
|
||||
[<CLIMutable>]
|
||||
type DefenseAction =
|
||||
{ ActionId : int
|
||||
Timestamp : DateTime }
|
||||
|
||||
[<CLIMutable>]
|
||||
type PlayerEntry =
|
||||
{ DiscordId : uint64
|
||||
Name : string
|
||||
Arsenal : int array
|
||||
Attacks : AttackAction array
|
||||
Defenses : DefenseAction array
|
||||
Bank : int }
|
||||
|
||||
let private actionToAttack (action : Action) (hack : AttackResult) =
|
||||
{ ActionId = action.ActionId
|
||||
Result = hack.Result
|
||||
Target = hack.Target
|
||||
Timestamp = action.Timestamp }
|
||||
|
||||
let private actionToDefense (action : Action) =
|
||||
{ ActionId = action.ActionId
|
||||
Timestamp = action.Timestamp }
|
||||
|
||||
let private attackToAction (attack : AttackAction) =
|
||||
{ ActionId = attack.ActionId
|
||||
Type = Attack { Target = attack.Target ; Result = attack.Result }
|
||||
Timestamp = attack.Timestamp }
|
||||
|
||||
let private defenseToAction (action : DefenseAction) =
|
||||
{ ActionId = action.ActionId
|
||||
Type = Defense
|
||||
Timestamp = action.Timestamp }
|
||||
|
||||
let private playerMap (player : PlayerData) = {
|
||||
DiscordId = player.DiscordId
|
||||
Name = player.Name
|
||||
Arsenal = player.Arsenal |> Array.map (fun w -> w.Id)
|
||||
Attacks = [||]
|
||||
Defenses = [||]
|
||||
Bank = int player.Bank
|
||||
}
|
||||
|
||||
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))
|
||||
Actions =
|
||||
let atks = player.Attacks |> Array.map attackToAction
|
||||
let dfns = player.Defenses |> Array.map defenseToAction
|
||||
Array.append atks dfns
|
||||
Bank = player.Bank * 1<GBT>
|
||||
}
|
||||
|
||||
|
||||
let mongo = MongoClient(Environment.GetEnvironmentVariable("CONN_STRING"))
|
||||
let db = mongo.GetDatabase("degenz")
|
||||
let players = db.GetCollection<BsonDocument>("players")
|
||||
@ -20,30 +82,32 @@ let tryFindPlayer (id : uint64) =
|
||||
| p -> return p
|
||||
.GetValue("Player")
|
||||
.ToBsonDocument()
|
||||
|> BsonSerializer.Deserialize<PlayerData>
|
||||
|> BsonSerializer.Deserialize<PlayerEntry>
|
||||
|> mapBack
|
||||
|> Some
|
||||
}
|
||||
|
||||
let insertNewPlayer (player : PlayerData) =
|
||||
async {
|
||||
let dict = [ KeyValuePair("Player" , player.ToBsonDocument() :> Object) ]
|
||||
let p = playerMap player
|
||||
let dict = [ KeyValuePair("Player" , p.ToBsonDocument() :> Object) ]
|
||||
do! BsonDocument(dict)
|
||||
|> players.InsertOneAsync
|
||||
|> Async.AwaitTask
|
||||
}
|
||||
|
||||
let deletePlayer (player : PlayerData) =
|
||||
async {
|
||||
let dict = [ KeyValuePair("Player" , player.ToBsonDocument() :> Object) ]
|
||||
do! BsonDocument(dict)
|
||||
|> players.InsertOneAsync
|
||||
|> Async.AwaitTask
|
||||
}
|
||||
|
||||
let updatePlayer player =
|
||||
//let deletePlayer (player : PlayerData) =
|
||||
// async {
|
||||
// let dict = [ KeyValuePair("Player" , player.ToBsonDocument() :> Object) ]
|
||||
// do! BsonDocument(dict)
|
||||
// |> players.InsertOneAsync
|
||||
// |> Async.AwaitTask
|
||||
// }
|
||||
//
|
||||
let updatePlayer (player : PlayerData) =
|
||||
async {
|
||||
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", player.DiscordId)
|
||||
let update = Builders<BsonDocument>.Update.Set("Player", player)
|
||||
let update = Builders<BsonDocument>.Update.Set("Player", playerMap player)
|
||||
return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
|
||||
}
|
||||
|
||||
|
@ -55,15 +55,17 @@ type HackResult =
|
||||
[<CLIMutable>]
|
||||
type DiscordPlayer = { Id: uint64; Name: string }
|
||||
|
||||
type Attack = {
|
||||
[<CLIMutable>]
|
||||
type AttackResult = {
|
||||
Result : bool
|
||||
Target : DiscordPlayer
|
||||
}
|
||||
|
||||
type ActionType =
|
||||
| Attack of target : DiscordPlayer * result : bool
|
||||
| Attack of AttackResult
|
||||
| Defense
|
||||
|
||||
[<CLIMutable>]
|
||||
type Action =
|
||||
{ ActionId : int
|
||||
Type : ActionType
|
||||
@ -79,13 +81,13 @@ type PlayerData =
|
||||
|
||||
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 = Hack)
|
||||
let shields player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Shield)
|
||||
let attacks player =
|
||||
player.Actions
|
||||
|> Array.choose (fun act -> match act.Type with Attack (t,r) -> Some (act,t,r) | 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 getAttacksFlat actions = actions |> Array.choose (fun act -> match act.Type with Attack (t,r) -> Some (act,t,r) | Defense -> None)
|
||||
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 {
|
||||
@ -105,29 +107,21 @@ let hackDescription = ""
|
||||
|
||||
let statusFormat p =
|
||||
$"Hacks: {Player.hacks p |> Array.toList}
|
||||
Shields: {Player.defenses 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 constructButtons (actionType: string) (playerInfo: string) (weapons: BattleItem array) =
|
||||
weapons
|
||||
|> Array.map (fun w -> DiscordButtonComponent(ButtonStyle.Primary, $"{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)
|
||||
|
||||
let getItemFromArmoury id = armoury |> Array.find (fun w -> w.Id = id)
|
||||
|
||||
let constructButtons (actionType: string) (playerInfo: string) (weapons: 'a array) =
|
||||
weapons
|
||||
|> Seq.map (fun hack -> DiscordButtonComponent(ButtonStyle.Primary, $"{actionType}-{hack}-{playerInfo}", $"{hack}"))
|
||||
|
||||
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 modifyPlayerBank player amount = { player with Bank = max (player.Bank + amount) 0<GBT> }
|
||||
|
||||
module Message =
|
||||
let sendFollowUpMessage (event : ComponentInteractionCreateEventArgs) msg =
|
||||
async {
|
||||
|
Loading…
x
Reference in New Issue
Block a user