diff --git a/Bot/Bot.fs b/Bot/Bot.fs index f75e40d..b49ff4b 100644 --- a/Bot/Bot.fs +++ b/Bot/Bot.fs @@ -90,7 +90,7 @@ GuildEnvironment.botUserArmory <- Some storeBot.CurrentUser stealBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously -inviterBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously +//inviterBot.ConnectAsync() |> Async.AwaitTask |> Async.RunSynchronously //let channel = hackerBattleBot.GetChannelAsync(1234uL) |> Async.AwaitTask |> Async.RunSynchronously //channel.invi diff --git a/Bot/Embeds.fs b/Bot/Embeds.fs index 8c847ad..e764d66 100644 --- a/Bot/Embeds.fs +++ b/Bot/Embeds.fs @@ -57,8 +57,7 @@ let pickDefense actionId player isTrainer = .WithDescription("Pick a shield to protect yourself from hacks") for shield in Inventory.getShields player.Inventory do - // TODO: This is returning a decimal so look into why - let hours = TimeSpan.FromMinutes(int shield.Cooldown).TotalHours + let hours = TimeSpan.FromMinutes(int shield.Cooldown).TotalHours |> int let against = WeaponClass.getGoodAgainst(shield.Class) |> snd embed.AddField(shield.Item.Name, $"Active {hours} hours\nDefeats {against}", true) |> ignore diff --git a/Bot/GameHelpers.fs b/Bot/GameHelpers.fs index 5a287fa..fb1c120 100644 --- a/Bot/GameHelpers.fs +++ b/Bot/GameHelpers.fs @@ -43,7 +43,7 @@ module Inventory = inventory |> List.choose (fun item -> match item with | Accessory a -> Some a | _ -> None) module WeaponClass = - let SameTargetAttackCooldown = TimeSpan.FromHours(1) + let SameTargetAttackCooldown = TimeSpan.FromHours(2) let getClassButtonColor item = match ItemDetails.getClass item with @@ -130,6 +130,6 @@ module Arsenal = let statusFormat p = let hacks = Player.getHackEvents p $"**Hacks:** {Inventory.getItemsByType ItemType.Hack p.Inventory |> battleItemFormat}\n - **Shields:** {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}" diff --git a/Bot/Games/HackerBattle.fs b/Bot/Games/HackerBattle.fs index 5051617..db0228a 100644 --- a/Bot/Games/HackerBattle.fs +++ b/Bot/Games/HackerBattle.fs @@ -65,7 +65,7 @@ let checkPlayerHasShieldSlotsAvailable player = | false -> Ok updatedPlayer let checkTargetHasFunds target player = - match target.Bank = 0 with + match target.Bank <= 0 with | true -> Error $"Looks like the poor bastard has no $GBT... pick a different victim." | false -> Ok player @@ -81,7 +81,6 @@ let runHackerBattle defender (hack : HackItem) = |> List.contains Weak let updateCombatants successfulHack (attacker : PlayerData) (defender : PlayerData) (hack : HackItem) prize = - // TODO: Look into the prizes and how we're handling them because it seems it can be negative let updatePlayer amount attack p = { p with Events = attack::p.Events ; Bank = max (p.Bank + amount) 0 } let event isDefenderEvent = @@ -162,6 +161,7 @@ let handleAttack (ctx : IDiscordContext) = |> Player.removeExpiredActions |> checkAlreadyHackedTarget defender >>= checkPlayerOwnsWeapon hack.Item + >>= checkTargetHasFunds defender >>= checkWeaponHasCooldown hack.Item |> function | Ok atkr -> diff --git a/Bot/Games/Thief.fs b/Bot/Games/Thief.fs index 233cc7d..57f2c49 100644 --- a/Bot/Games/Thief.fs +++ b/Bot/Games/Thief.fs @@ -82,7 +82,7 @@ let checkVictimStealingCooldown defender attacker = | None -> Ok attacker let checkTargetHasFunds target player = - match target.Bank = 0 with + match target.Bank <= 0 with | true -> Error $"Looks like the poor bastard has no $GBT... pick a different victim." | false -> Ok player diff --git a/Bot/Games/Trainer.fs b/Bot/Games/Trainer.fs index 3ce6dfd..dbebebd 100644 --- a/Bot/Games/Trainer.fs +++ b/Bot/Games/Trainer.fs @@ -12,18 +12,21 @@ let Sensei = { Id = GuildEnvironment.botIdHackerBattle ; Name = "Sensei" } let defaultHack = Armory.weapons |> Inventory.findHackById (int ItemId.Virus) let defaultShield = Armory.weapons |> Inventory.findShieldById (int ItemId.Firewall) -let TrainerEvents = [ - { Timestamp = System.DateTime.UtcNow - Cooldown = defaultHack.Cooldown +let HackEvent = { + Timestamp = System.DateTime.UtcNow + Cooldown = 1 Type = Hacking { Adversary = Sensei Success = true IsInstigator = true - HackId = defaultHack.Item.Id } } - { Timestamp = System.DateTime.UtcNow + HackId = defaultHack.Item.Id + } +} +let ShieldEvent = { + Timestamp = System.DateTime.UtcNow Cooldown = defaultShield.Cooldown - Type = Shielding defaultShield.Item.Id } -] + Type = Shielding defaultShield.Item.Id +} let sendInitialEmbed (client : DiscordClient) = async { @@ -166,27 +169,39 @@ let handleHack (ctx : IDiscordContext) = let handleArsenal (ctx : IDiscordContext) = PlayerInteractions.executePlayerAction ctx (fun player -> async { - let hasStockWeapons = - // TODO: This didn't seem to work and someone was gifted both weapons when they already owned one - player.Inventory - |> List.choose (fun item -> if item.Id = defaultHack.Item.Id || item.Id = defaultShield.Item.Id then Some item else None) - |> List.length > 0 - let updatedPlayer = - if not hasStockWeapons then { - Player.removeExpiredActions player with - Events = TrainerEvents @ player.Events - Inventory = Hack defaultHack::Shield defaultShield::player.Inventory - } - else - Player.removeExpiredActions player - if not hasStockWeapons then - do! - [ DbService.addPlayerEvent player.DiscordId TrainerEvents.[0] - DbService.addPlayerEvent player.DiscordId TrainerEvents.[1] - DbService.updatePlayer updatedPlayer ] - |> Async.Parallel - |> Async.Ignore - let embed = Embeds.getArsenalEmbed updatedPlayer + let hack = + if player.Inventory |> List.exists (fun i -> i.Id = defaultHack.Item.Id) + then [] + else [ Hack defaultHack ] + let shield = + if player.Inventory |> List.exists (fun i -> i.Id = defaultShield.Item.Id) + then [] + else [ Shield defaultShield ] + let shieldEvent = + let hasShield = + player + |> Player.removeExpiredActions + |> fun p -> p.Events + |> List.exists (fun e -> match e.Type with Shielding shieldId -> shieldId = defaultShield.Item.Id | _ -> false) + if hasShield + then [] + else [ ShieldEvent ] + let updatedPlayer = { + Player.removeExpiredActions player with + Events = shieldEvent @ player.Events + Inventory = hack @ shield @ player.Inventory + } + if not (List.isEmpty hack) || not (List.isEmpty shield) then + do! DbService.updatePlayer updatedPlayer |> Async.Ignore + if not (List.isEmpty shieldEvent) then + do! DbService.addPlayerEvent player.DiscordId (List.head shieldEvent) |> Async.Ignore + + let playerForEmbed = { + player with + Events = [ HackEvent ; ShieldEvent ] + Inventory = hack @ shield @ player.Inventory + } + let embed = Embeds.getArsenalEmbed playerForEmbed do! ctx.FollowUp(embed) |> Async.AwaitTask let! completed = DbService.checkHasAchievement player.DiscordId trainerAchievement diff --git a/Bot/Items.json b/Bot/Items.json index ff95a07..f4a7c1f 100644 --- a/Bot/Items.json +++ b/Bot/Items.json @@ -77,7 +77,7 @@ "Fields": [ { "Class": 2, - "Cooldown": 380, + "Cooldown": 360, "Item": { "Id": 8, "Name": "Cypher",