discord-bot-game/Bot/GameHelpers.fs

140 lines
6.6 KiB
Forth

namespace Degenz
open System
open DSharpPlus
open DSharpPlus.Entities
open Degenz
module Inventory =
let getItemsByType itemType inventory =
match itemType with
| ItemType.Hack -> inventory |> List.filter (fun item -> match item.Type with ItemType.Hack _ -> true | _ -> false)
| ItemType.Shield -> inventory |> List.filter (fun item -> match item.Type with ItemType.Shield _ -> true | _ -> false)
| ItemType.Food -> inventory |> List.filter (fun item -> match item.Type with ItemType.Food _ -> true | _ -> false)
| ItemType.Accessory -> inventory |> List.filter (fun item -> match item.Type with ItemType.Accessory _ -> true | _ -> false)
| ItemType.Jpeg -> inventory |> List.filter (fun item -> match item.Type with ItemType.Jpeg _ -> true | _ -> false)
| ItemType.Whitelist -> inventory |> List.filter (fun item -> match item.Type with ItemType.Whitelist _ -> true | _ -> false)
| ItemType.Misc -> inventory |> List.filter (fun item -> match item.Type with ItemType.Misc _ -> true | _ -> false)
let findItemById id (inventory : Inventory) = inventory |> List.find (fun item -> item.Id = id)
let getBuyPrice item = match item.Attributes with CanBuy price -> price | _ -> 0<GBT>
let getHackItem item =
match item.Type , item.Attributes with
| ItemType.Hack , CanBuy buyPrice & CanSell _ & CanAttack power & CanRateLimit cooldown & CanClass ``class``->
Some { Id = item.Id
Name = item.Name
Price = buyPrice
Cooldown = cooldown
IconUrl = item.IconUrl
ImageUrl = item.ImageUrl
Power = power
Class = ``class`` }
| _ -> None
let getShieldItem item =
match item.Type , item.Attributes with
| ItemType.Shield , CanBuy buyPrice & CanSell _ & CanDefend resistance & CanRateLimit cooldown & CanClass ``class`` ->
Some { Id = item.Id
Name = item.Name
Price = buyPrice
Cooldown = cooldown
IconUrl = item.IconUrl
ImageUrl = item.ImageUrl
Resistance = resistance
Class = ``class`` }
| _ -> None
// let findHackById id inventory =
// inventory |> List.pick (fun item -> match item with | Hack h -> (if h.Item.Id = id then Some h else None) | _ -> None)
// let findShieldById id inventory =
// inventory |> List.pick (fun item -> match item with | Shield s -> (if s.Item.Id = id then Some s else None) | _ -> None)
// let findFoodById id inventory =
// inventory |> List.pick (fun item -> match item with | Food f -> (if f.Item.Id = id then Some f else None) | _ -> None)
// let findAccessoryById id inventory =
// inventory |> List.pick (fun item -> match item with | Accessory a -> (if a.Item.Id = id then Some a else None) | _ -> None)
//
let getHacks inventory = inventory |> List.choose getHackItem
let getShields inventory = inventory |> List.choose getShieldItem
let getFoods inventory =
inventory |> List.choose (fun item -> match item.Type with | ItemType.Food -> Some item | _ -> None)
let getAccessories inventory =
inventory |> List.choose (fun item -> match item.Type with | ItemType.Accessory -> Some item | _ -> None)
module WeaponClass =
let SameTargetAttackCooldown = TimeSpan.FromHours(4)
let getClassButtonColor item =
match item.Attributes with
| CanClass "NETWORK" -> ButtonStyle.Danger
| CanClass "EXPLOIT" -> ButtonStyle.Primary
| CanClass "PENETRATION" -> ButtonStyle.Success
| _ -> ButtonStyle.Primary
let getClassEmbedColor item =
match item.Attributes with
| CanClass "NETWORK" -> DiscordColor.Red
| CanClass "EXPLOIT" -> DiscordColor.Blurple
| CanClass "PENETRATION" -> DiscordColor.Green
| _ -> DiscordColor.Blurple
let getGoodAgainst = function
| "NETWORK" -> ( ItemId.FIREWALL , ItemId.VIRUS )
| "EXPLOIT" -> ( ItemId.ENCRYPTION , ItemId.REMOTE )
| "PENETRATION" -> ( ItemId.CYPHER , ItemId.WORM )
| _ -> ( ItemId.FIREWALL , ItemId.VIRUS )
module Player =
let getHackEvents player =
player.Events
|> List.filter (fun act -> match act.Type with PlayerEventType.Hacking h -> h.IsInstigator | _ -> false)
let getShieldEvents player =
player.Events
|> List.filter (fun act -> match act.Type with PlayerEventType.Shielding _ -> true | _ -> false)
let removeExpiredActions player =
let actions =
player.Events
|> List.filter (fun (act : PlayerEvent) ->
let cooldown = TimeSpan.FromMinutes(int act.Cooldown)
DateTime.UtcNow - act.Timestamp < cooldown)
{ player with Events = actions }
let modifyBank (player : PlayerData) amount = { player with Bank = max (player.Bank + amount) 0<GBT> }
module Arsenal =
let weapons = DbService.getWeapons () |> Async.RunSynchronously
let battleItemFormat (items : Inventory) =
match items with
| [] -> "None"
| _ -> items |> List.map (fun item -> item.Name) |> String.concat ", "
let actionFormat items (actions : PlayerEvent List) =
match actions with
| [] -> "None"
| acts ->
acts
|> List.map (fun event ->
match event.Type with
| Hacking h ->
let item = items |> Inventory.findItemById h.HackId
let cooldown = Messaging.getTimeText false WeaponClass.SameTargetAttackCooldown event.Timestamp
$"Hacked {h.Adversary.Name} with {item.Name} {cooldown} ago"
| Shielding id ->
let item = items |> Inventory.findItemById id
let cooldown = Messaging.getTimeText true (TimeSpan.FromMinutes(int event.Cooldown)) event.Timestamp
$"{item.Name} Shield active for {cooldown}"
| _ -> "")
|> List.filter (String.IsNullOrWhiteSpace >> not)
|> String.concat "\n"
let statusFormat p =
let hacks = Player.getHackEvents p
$"**Hacks:** {Inventory.getItemsByType ItemType.Hack p.Inventory |> battleItemFormat}\n
**Shields:** {Inventory.getItemsByType ItemType.Shield p.Inventory |> battleItemFormat}\n
**Hack Attacks:**\n{hacks |> List.take (min hacks.Length 10) |> actionFormat weapons}\n
**Active Shields:**\n{Player.getShieldEvents p |> actionFormat weapons}"