namespace Degenz open DSharpPlus open DSharpPlus.Entities open Newtonsoft.Json module Armory = let battleItems = let file = System.IO.File.ReadAllText("Items.json") // let file = System.IO.File.ReadAllText("Bot/Items.json") JsonConvert.DeserializeObject(file) |> Array.toList let hacks = battleItems |> List.filter (fun item -> match item.Type with Hack _ -> true | _ -> false) let shields = battleItems |> List.filter (fun item -> match item.Type with Shield _ -> true | _ -> false) let getItem itemId = battleItems |> List.find (fun item -> item.Id = itemId) let getHackItems inventory = inventory |> List.filter (fun item -> match item.Type with Hack _ -> true | _ -> false) |> List.sortBy (fun item -> item.Id) let getShieldItems inventory = inventory |> List.filter (fun item -> match item.Type with Shield _ -> true | _ -> false) |> List.sortBy (fun item -> item.Id) let getHacks : HackItem list = battleItems |> List.choose (fun item -> match item.Type with | Hack(power, hackClass, cooldown) -> Some (item , power, hackClass, cooldown) | _ -> None) |> List.sortBy (fun (item,_,_,_) -> item.Id) let getShields : ShieldItem list = battleItems |> List.choose (fun item -> match item.Type with | Shield(hackClass, cooldown) -> Some (item,hackClass,cooldown) | _ -> None) |> List.sortBy (fun (item,_,_) -> item.Id) let getHackById id = getHacks |> List.find (fun (item,_,_,_) -> item.Id = id) let getShieldById id = getShields |> List.find (fun (item,_,_) -> item.Id = id) module WeaponClass = // TODO: Find a different place to put this let SameTargetAttackCooldown = System.TimeSpan.FromHours(1) let getClassButtonColor item = match item.Type with | Hack (_,0,_) | Shield (0,_) -> ButtonStyle.Danger | Hack (_,1,_) | Shield (1,_) -> ButtonStyle.Primary | Hack (_,2,_) | Shield (2,_) -> ButtonStyle.Success | _ -> ButtonStyle.Primary let getClassEmbedColor item = match item.Type with | Hack (_,0,_) | Shield (0,_) -> DiscordColor.Red | Hack (_,1,_) | Shield (1,_) -> DiscordColor.Blurple | Hack (_,2,_) | Shield (2,_) -> DiscordColor.Green | _ -> DiscordColor.Blurple let getGoodAgainst = function | 0 -> ( ItemId.Firewall , ItemId.Virus ) | 1 -> ( ItemId.Encryption , ItemId.RemoteAccess ) | _ -> ( ItemId.Cypher , ItemId.Worm ) module Player = let getHackItems player = player.Inventory |> List.filter (fun item -> match item.Type with Hack _ -> true | _ -> false) |> List.sortBy (fun item -> item.Id) let getShieldItems player = player.Inventory |> List.filter (fun item -> match item.Type with Shield _ -> true | _ -> false) |> List.sortBy (fun item -> item.Id) let getHacks player : HackItem list = player.Inventory |> List.choose (fun item -> match item.Type with | Hack(power, hackClass, cooldown) -> Some (item , power, hackClass, cooldown) | _ -> None) |> List.sortBy (fun (item,_,_,_) -> item.Id) let getShields player : ShieldItem list = player.Inventory |> List.choose (fun item -> match item.Type with | Shield(hackClass, cooldown) -> Some (item , hackClass, cooldown) | _ -> None) |> List.sortBy (fun (item,_,_) -> item.Id) let getHackEvents player = player.Events |> Array.filter (fun act -> match act.Type with PlayerEventType.Hacking h -> h.IsInstigator | _ -> false) let getShieldEvents player = player.Events |> Array.filter (fun act -> match act.Type with PlayerEventType.Shielding _ -> true | _ -> false) let removeExpiredActions player = let actions = player.Events |> Array.filter (fun (act : PlayerEvent) -> let cooldown = System.TimeSpan.FromMinutes(int act.Cooldown) System.DateTime.UtcNow - act.Timestamp < cooldown) { player with Events = actions } let modifyBank (player : PlayerData) amount = { player with Bank = max (player.Bank + amount) 0 } let getStat statId player = player.Stats |> List.tryFind (fun stat -> statId = stat.Id) |> Option.map (fun stat -> stat.Amount) |> Option.defaultValue 0 module Arsenal = let battleItemFormat (items : Item list) = match items with | [] -> "None" | _ -> items |> List.map (fun item -> item.Name) |> String.concat ", " let actionFormat (actions : PlayerEvent array) = match actions with | [||] -> "None" | acts -> acts |> Array.map (fun act -> match act.Type with | Hacking h -> let item = Armory.getItem h.HackId let cooldown = Messaging.getTimeText false WeaponClass.SameTargetAttackCooldown act.Timestamp $"Hacked {h.Adversary.Name} with {item.Name} {cooldown} ago" | Shielding id -> let item = Armory.getItem id let cooldown = Messaging.getTimeText true (System.TimeSpan.FromMinutes(int act.Cooldown)) act.Timestamp $"{item.Name} Shield active for {cooldown}" | _ -> "") |> Array.filter (System.String.IsNullOrWhiteSpace >> not) |> String.concat "\n" let statusFormat p = let hacks = Player.getHackEvents p $"**Hacks:** {Player.getHackItems p |> battleItemFormat}\n **Shields:** {Player.getShieldItems p |> battleItemFormat}\n **Hack Attacks:**\n{ hacks |> Array.take (min hacks.Length 10) |> actionFormat}\n **Active Shields:**\n{Player.getShieldEvents p |> actionFormat}"