diff --git a/Bot/DbService.fs b/Bot/DbService.fs index 081b8d5..630e936 100644 --- a/Bot/DbService.fs +++ b/Bot/DbService.fs @@ -15,9 +15,9 @@ type User = { let mapBack user : PlayerData = { DiscordId = user.DiscordId Name = user.Name - Inventory = user.Inventory |> List.choose (fun id -> Armory.battleItems |> List.tryFind (fun item -> item.Id = id)) + Inventory = user.Inventory |> List.choose (fun id -> Armory.weapons |> List.tryFind (fun item -> item.Id = id)) Events = [||] - Stats = [ { Id = StatId.Strength ; Amount = user.Strength } ] + Stats = [ { Id = StatId.Strength ; Amount = user.Strength ; LastRead = DateTime.UtcNow} ] Bank = user.Bank } diff --git a/Bot/GameHelpers.fs b/Bot/GameHelpers.fs index 2218b58..1524e73 100644 --- a/Bot/GameHelpers.fs +++ b/Bot/GameHelpers.fs @@ -1,32 +1,17 @@ namespace Degenz +open System open DSharpPlus open DSharpPlus.Entities open Newtonsoft.Json module Armory = - let battleItems = + let weapons = 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 getHackById id inventory = inventory |> getHackItems |> List.find (fun item -> item.Id = id) - let getShieldById id inventory = inventory |> getShieldItems |> List.find (fun item -> item.Id = id) - module Inventory = let itemToHack item power hackClass cooldown = { Id = item.Id @@ -70,6 +55,8 @@ module Inventory = inventory |> List.choose (fun item -> match item.Type with Shield (cl,co) -> Some (itemToShield item cl co) | _ -> None) |> List.sortBy (fun item -> item.Id) + let findItemById id inventory = inventory |> List.find (fun item -> item.Id = id) + let tryFindItemById id inventory = inventory |> List.tryFind (fun item -> item.Id = id) let findHackById id inventory = inventory |> getHackItems |> List.pick (fun item -> if item.Id = id then Some item else None) let findShieldById id inventory = @@ -126,6 +113,19 @@ module Player = |> Option.map (fun stat -> stat.Amount) |> Option.defaultValue 0 +module PlayerStats = + let Strength = { Id = StatId.Strength ; BaseDecayRate = 5.0f ; BaseMinMax = Range(0, 100) } + let Focus = { Id = StatId.Focus ; BaseDecayRate = 5.0f ; BaseMinMax = Range(0, 100) } + let Luck = { Id = StatId.Luck ; BaseDecayRate = 5.0f ; BaseMinMax = Range(0, 100) } + let Charisma = { Id = StatId.Charisma ; BaseDecayRate = 5.0f ; BaseMinMax = Range(0, 100) } + + let stats = [| Strength ; Focus ; Luck ; Charisma |] + let statConsumableMap = + [ ( StatId.Strength , 12 ) + ( StatId.Focus , 13 ) + ( StatId.Luck , 14 ) + ( StatId.Charisma , 15 ) ] + module Arsenal = let battleItemFormat (items : Item list) = match items with @@ -140,11 +140,11 @@ module Arsenal = |> Array.map (fun act -> match act.Type with | Hacking h -> - let item = Armory.getItem h.HackId + let item = Armory.weapons |> Inventory.findHackById 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 item = Armory.weapons |> Inventory.findHackById id let cooldown = Messaging.getTimeText true (System.TimeSpan.FromMinutes(int act.Cooldown)) act.Timestamp $"{item.Name} Shield active for {cooldown}" | _ -> "") @@ -157,23 +157,3 @@ module Arsenal = **Shields:** {Inventory.filterByShields p.Inventory |> battleItemFormat}\n **Hack Attacks:**\n{ hacks |> Array.take (min hacks.Length 10) |> actionFormat}\n **Active Shields:**\n{Player.getShieldEvents p |> actionFormat}" - -module Items = - let mapHack fn inventory = - inventory - |> List.choose (fun item -> - match item.Type with - | Hack(power, hackClass, cooldown) -> Some <| fn item power hackClass cooldown - | _ -> None) - let mapShield fn inventory = - inventory - |> List.choose (fun item -> - match item.Type with - | Shield(hackClass, cooldown) -> Some <| fn item hackClass cooldown - | _ -> None) - let doShields fn inventory = - inventory - |> List.iter (fun item -> - match item.Type with - | Shield(hackClass, cooldown) -> fn item hackClass cooldown - | _ -> ()) diff --git a/Bot/GameTypes.fs b/Bot/GameTypes.fs index b9e9454..717f42a 100644 --- a/Bot/GameTypes.fs +++ b/Bot/GameTypes.fs @@ -32,26 +32,13 @@ type Stat = { type ActiveStat = { Id : StatId Amount : int + LastRead : DateTime } -module PlayerStats = - let Strength = { Id = StatId.Strength ; BaseDecayRate = 5.0f ; BaseMinMax = Range(0, 100) } - let Focus = { Id = StatId.Focus ; BaseDecayRate = 5.0f ; BaseMinMax = Range(0, 100) } - let Luck = { Id = StatId.Luck ; BaseDecayRate = 5.0f ; BaseMinMax = Range(0, 100) } - let Charisma = { Id = StatId.Charisma ; BaseDecayRate = 5.0f ; BaseMinMax = Range(0, 100) } - - let stats = [| Strength ; Focus ; Luck ; Charisma |] - let statConsumableMap = - [ ( StatId.Strength , 12 ) - ( StatId.Focus , 13 ) - ( StatId.Luck , 14 ) - ( StatId.Charisma , 15 ) ] - type HackResult = | Strong | Weak -[] type DiscordPlayer = { Id: uint64; Name: string } with static member empty = { Id = 0uL ; Name = "None" } @@ -90,11 +77,27 @@ type ShieldItem = { Cooldown : int } +type FoodItem = { + Id : int + Name : string + Price : int + TargetStat : StatId + BoostAmount : int +} + +type AccessoryItem = { + Id : int + Name : string + Price : int + TargetStat : StatId + PassiveBoost : int +} + type ItemType = | Hack of power : int * hackClass : int * cooldown : int | Shield of shieldClass : int * cooldown : int - | Food of effect : (Item -> PlayerData -> PlayerData) - | Accessory of effect : (Item -> PlayerData -> PlayerData) + | Food of targetStat : StatId * boostAmount : int + | Accessory of targetStat : StatId * passiveBoost : int and Item = { Id : int Name : string diff --git a/Bot/Games/HackerBattle.fs b/Bot/Games/HackerBattle.fs index 10c5b94..31ccd1e 100644 --- a/Bot/Games/HackerBattle.fs +++ b/Bot/Games/HackerBattle.fs @@ -150,7 +150,7 @@ let handleAttack (ctx : IDiscordContext) = executePlayerAction ctx (fun attacker -> async { let tokens = ctx.GetInteractionId().Split("-") let hackId = int tokens.[1] - let hack = Armory.battleItems |> Inventory.findHackById hackId + let hack = Armory.weapons |> Inventory.findHackById hackId let hackAsItem = Inventory.hackToItem hack let resultId , targetId = UInt64.TryParse tokens.[2] let! resultTarget = DbService.tryFindPlayer GuildEnvironment.pgDb targetId @@ -187,7 +187,7 @@ let handleDefense (ctx : IDiscordContext) = executePlayerAction ctx (fun player -> async { let tokens = ctx.GetInteractionId().Split("-") let shieldId = int tokens.[1] - let shield = Armory.battleItems |> Inventory.findShieldById shieldId + let shield = Armory.weapons |> Inventory.findShieldById shieldId let shieldAsItem = Inventory.shieldToItem shield do! player diff --git a/Bot/Games/Store.fs b/Bot/Games/Store.fs index ce5dde8..6b9029b 100644 --- a/Bot/Games/Store.fs +++ b/Bot/Games/Store.fs @@ -84,7 +84,7 @@ let checkHasItemsInArsenal itemType items player = let buy getItems (ctx : IDiscordContext) = executePlayerAction ctx (fun player -> async { - let itemStore = getBuyItemsEmbed (getItems player.Inventory) (getItems Armory.battleItems) + let itemStore = getBuyItemsEmbed (getItems player.Inventory) (getItems Armory.weapons) do! ctx.FollowUp itemStore |> Async.AwaitTask }) @@ -100,7 +100,7 @@ let sell itemType getItems (ctx : IDiscordContext) = // TODO: When you buy a shield, prompt the user to activate it let handleBuyItem (ctx : IDiscordContext) itemId = executePlayerAction ctx (fun player -> async { - let item = Armory.getItem itemId + let item = Armory.weapons |> Inventory.findItemById itemId do! player |> checkHasSufficientFunds item >>= checkAlreadyOwnsItem item @@ -114,7 +114,7 @@ let handleBuyItem (ctx : IDiscordContext) itemId = let handleSell (ctx : IDiscordContext) itemId = executePlayerAction ctx (fun player -> async { - let item = Armory.getItem itemId + let item = Armory.weapons |> Inventory.findItemById itemId do! player |> checkSoldItemAlready item @@ -161,10 +161,10 @@ type Store() = } [] - member _.BuyHack (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (buy Armory.getHackItems) + member _.BuyHack (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (buy Inventory.filterByHacks) [] - member this.BuyShield (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (buy Armory.getShieldItems) + member this.BuyShield (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (buy Inventory.filterByShields) [] member this.SellHack (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (sell "Hacks" Inventory.filterByHacks) diff --git a/Bot/Games/Trainer.fs b/Bot/Games/Trainer.fs index e9873d7..24df899 100644 --- a/Bot/Games/Trainer.fs +++ b/Bot/Games/Trainer.fs @@ -9,8 +9,8 @@ open Degenz.Messaging let trainerAchievement = "FINISHED_TRAINER" let Sensei = { Id = GuildEnvironment.botIdHackerBattle ; Name = "Sensei" } -let defaultHack = Armory.battleItems |> Inventory.findHackById (int ItemId.Virus) -let defaultShield = Armory.battleItems |> Inventory.findShieldById (int ItemId.Firewall) +let defaultHack = Armory.weapons |> Inventory.findHackById (int ItemId.Virus) +let defaultShield = Armory.weapons |> Inventory.findShieldById (int ItemId.Firewall) let TrainerEvents = [| { Timestamp = System.DateTime.UtcNow