136 lines
6.4 KiB
Forth
136 lines
6.4 KiB
Forth
namespace Degenz
|
|
|
|
open System
|
|
open DSharpPlus
|
|
open DSharpPlus.Entities
|
|
open Degenz
|
|
open Newtonsoft.Json
|
|
|
|
module Armory =
|
|
// let weapons : ItemDetails list= []
|
|
let weapons : ItemDetails list =
|
|
let file = System.IO.File.ReadAllText("Items.json")
|
|
// let file = System.IO.File.ReadAllText("Bot/Items.json")
|
|
JsonConvert.DeserializeObject<ItemDetails array>(file)
|
|
|> Array.toList
|
|
|
|
module Inventory =
|
|
let getItemsByType itemType inventory =
|
|
match itemType with
|
|
| ItemType.Hack -> inventory |> List.filter (fun item -> match item with Hack _ -> true | _ -> false)
|
|
| ItemType.Shield -> inventory |> List.filter (fun item -> match item with Shield _ -> true | _ -> false)
|
|
| ItemType.Food -> inventory |> List.filter (fun item -> match item with Food _ -> true | _ -> false)
|
|
| ItemType.Accessory -> inventory |> List.filter (fun item -> match item with Accessory _ -> true | _ -> false)
|
|
|
|
let findItemById id (inventory : Inventory) = inventory |> List.find (fun item -> item.Id = id)
|
|
|
|
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 (fun item -> match item with | Hack h -> Some h | _ -> None)
|
|
let getShields inventory =
|
|
inventory |> List.choose (fun item -> match item with | Shield s -> Some s | _ -> None)
|
|
let getFoods inventory =
|
|
inventory |> List.choose (fun item -> match item with | Food f -> Some f | _ -> None)
|
|
let getAccessories inventory =
|
|
inventory |> List.choose (fun item -> match item with | Accessory a -> Some a | _ -> None)
|
|
|
|
module WeaponClass =
|
|
let SameTargetAttackCooldown = TimeSpan.FromHours(2)
|
|
|
|
let getClassButtonColor item =
|
|
match ItemDetails.getClass item with
|
|
| 0 -> ButtonStyle.Danger
|
|
| 1 -> ButtonStyle.Primary
|
|
| 2 -> ButtonStyle.Success
|
|
| _ -> ButtonStyle.Primary
|
|
|
|
let getClassEmbedColor item =
|
|
match ItemDetails.getClass item with
|
|
| 0 -> DiscordColor.Red
|
|
| 1 -> DiscordColor.Blurple
|
|
| 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 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 PlayerStats =
|
|
// 4.17f would go from 100 to 0 in roughly 24 hours
|
|
let Strength = { Id = StatId.Strength ; BaseDecayRate = 4.17 ; BaseRange = Range.normalized }
|
|
let Focus = { Id = StatId.Focus ; BaseDecayRate = 4.17 ; BaseRange = Range.normalized }
|
|
let Luck = { Id = StatId.Luck ; BaseDecayRate = 4.17 ; BaseRange = Range.normalized }
|
|
let Charisma = { Id = StatId.Charisma ; BaseDecayRate = 4.17 ; BaseRange = Range.normalized }
|
|
|
|
let stats = [ Strength ; Focus ; Luck ; Charisma ]
|
|
|
|
let calculateActiveStat statId amount items =
|
|
let statConfig = stats |> List.find (fun s -> s.Id = statId)
|
|
// let hoursElapsed = (DateTime.UtcNow - lastRead).Hours
|
|
// let totalDecay = float hoursElapsed * statConfig.BaseDecayRate
|
|
let modMinMax =
|
|
let min = items |> List.sumBy (fun item -> match item with | Accessory a -> a.FloorBoost | _ -> 0)
|
|
let max = items |> List.sumBy (fun item -> match item with | Accessory a -> a.CeilBoost | _ -> 0)
|
|
Range.create (statConfig.BaseRange.Min + min) (statConfig.BaseRange.Max + max)
|
|
let amountAfterDecay = modMinMax |> Range.constrain amount
|
|
{ Id = statId ; Amount = amountAfterDecay ; ModRange = modMinMax ; LastRead = DateTime.UtcNow }
|
|
|
|
module Arsenal =
|
|
let battleItemFormat (items : ItemDetails list) =
|
|
match items with
|
|
| [] -> "None"
|
|
| _ -> items |> List.map (fun item -> item.Name) |> String.concat ", "
|
|
|
|
let actionFormat (actions : PlayerEvent List) =
|
|
match actions with
|
|
| [] -> "None"
|
|
| acts ->
|
|
acts
|
|
|> List.map (fun event ->
|
|
match event.Type with
|
|
| Hacking h ->
|
|
let item = Armory.weapons |> Inventory.findHackById h.HackId
|
|
let cooldown = Messaging.getTimeText false WeaponClass.SameTargetAttackCooldown event.Timestamp
|
|
$"Hacked {h.Adversary.Name} with {item.Item.Name} {cooldown} ago"
|
|
| Shielding id ->
|
|
let item = Armory.weapons |> Inventory.findShieldById id
|
|
let cooldown = Messaging.getTimeText true (TimeSpan.FromMinutes(int event.Cooldown)) event.Timestamp
|
|
$"{item.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}\n
|
|
**Active Shields:**\n{Player.getShieldEvents p |> actionFormat}"
|