diff --git a/Bot/Game.fs b/Bot/Game.fs index 697a267..ae6f695 100644 --- a/Bot/Game.fs +++ b/Bot/Game.fs @@ -76,7 +76,7 @@ module Player = let getShields (player : PlayerData) = getItems ItemType.Shield player let getHackEvents player = player.Events - |> Array.filter (fun act -> match act.Type with PlayerEventType.Hacking _ -> true | _ -> false) + |> 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) diff --git a/Bot/HackerBattle.fs b/Bot/HackerBattle.fs index ab53a0c..37b1182 100644 --- a/Bot/HackerBattle.fs +++ b/Bot/HackerBattle.fs @@ -15,25 +15,29 @@ let checkPlayerIsAttackingThemselves defender attacker = | false -> Ok attacker let checkAlreadyHackedTarget defender attacker = - defender.Events + defender + |> Player.removeExpiredActions + |> fun d -> d.Events |> Array.tryFind (fun event -> match event.Type with | Hacking h -> h.Adversary.Id = attacker.DiscordId && h.IsInstigator = false | _ -> false) |> function | Some event -> - let cooldown = getTimeText true Game.SameTargetAttackCooldown event.Timestamp - Error $"You can only hack the same target once every {Game.SameTargetAttackCooldown.Hours} hours, wait {cooldown} to attempt another hack on <@{defender.DiscordId}>." + let cooldown = TimeSpan.FromMinutes(int event.Cooldown) + let cooldownText = getTimeText true cooldown event.Timestamp + Error $"You can only hack the same target once every {cooldown.Hours} hours, wait {cooldownText} to attempt another hack on <@{defender.DiscordId}>." | None -> Ok attacker let checkWeaponHasCooldown (weapon : Item) attacker = attacker.Events - |> Array.tryPick (fun a -> + |> Array.tryFind (fun a -> match a.Type with - | Hacking h -> if h.HackId = weapon.Id then Some ( h , a ) else None - | _ -> None) + | Hacking h -> h.HackId = weapon.Id + | Shielding id -> id = weapon.Id + | _ -> false) |> function - | Some ( _ , event ) -> + | Some event -> let cooldown = getTimeText true (TimeSpan.FromMinutes(int event.Cooldown)) event.Timestamp Error $"{weapon.Name} is still active, it will expire in {cooldown}." | None -> Ok attacker @@ -86,10 +90,12 @@ let updateCombatants successfulHack (attacker : PlayerData) (defender : PlayerDa } { Type = Hacking hackEvent Timestamp = DateTime.UtcNow - Cooldown = if isDefenderEvent then Game.SameTargetAttackCooldown.Minutes * 1 else hack.Cooldown } + Cooldown = if isDefenderEvent then int Game.SameTargetAttackCooldown.TotalMinutes * 1 else hack.Cooldown } [ DbService.updatePlayer GuildEnvironment.pgDb <| updatePlayer prize (event false) attacker - DbService.updatePlayer GuildEnvironment.pgDb <| updatePlayer -prize (event true) defender ] + DbService.updatePlayer GuildEnvironment.pgDb <| updatePlayer -prize (event true) defender + DbService.addPlayerEvent GuildEnvironment.pgDb attacker.DiscordId (event false) + DbService.addPlayerEvent GuildEnvironment.pgDb defender.DiscordId (event true) ] |> Async.Parallel |> Async.Ignore @@ -192,7 +198,9 @@ let handleDefense (ctx : IDiscordContext) = Cooldown = shield.Cooldown Timestamp = DateTime.UtcNow } - do! DbService.updatePlayer GuildEnvironment.pgDb <| { p with Events = Array.append [| defense |] p.Events } + do! DbService.updatePlayer GuildEnvironment.pgDb p + |> Async.Ignore + do! DbService.addPlayerEvent GuildEnvironment.pgDb p.DiscordId defense |> Async.Ignore let builder = DiscordMessageBuilder() builder.WithContent($"{ctx.GetDiscordMember().Username} has protected their system!") |> ignore diff --git a/Bot/Trainer.fs b/Bot/Trainer.fs index c93dd0e..e76577d 100644 --- a/Bot/Trainer.fs +++ b/Bot/Trainer.fs @@ -144,8 +144,8 @@ let handleHack (ctx : IDiscordContext) = let sb = StringBuilder("Here, ") - let! isFirstTrainer = DbService.checkHasAchievement GuildEnvironment.pgDb player.DiscordId trainerAchievement - if isFirstTrainer then + let! completed = DbService.checkHasAchievement GuildEnvironment.pgDb player.DiscordId trainerAchievement + if not completed then do! DbService.addAchievement GuildEnvironment.pgDb player.DiscordId trainerAchievement |> Async.Ignore @@ -174,13 +174,17 @@ let handleArsenal (ctx : IDiscordContext) = else Player.removeExpiredActions player if not hasStockWeapons then - do! DbService.updatePlayer GuildEnvironment.pgDb updatedPlayer + do! + [ DbService.addPlayerEvent GuildEnvironment.pgDb player.DiscordId TrainerEvents.[0] + DbService.addPlayerEvent GuildEnvironment.pgDb player.DiscordId TrainerEvents.[1] + DbService.updatePlayer GuildEnvironment.pgDb updatedPlayer ] + |> Async.Parallel |> Async.Ignore let embed = Embeds.getArsenalEmbed updatedPlayer do! ctx.FollowUp(embed) |> Async.AwaitTask - let! isFirstTrainer = DbService.checkHasAchievement GuildEnvironment.pgDb player.DiscordId trainerAchievement - if isFirstTrainer then + let! completed = DbService.checkHasAchievement GuildEnvironment.pgDb player.DiscordId trainerAchievement + if not completed then do! Async.Sleep 3000 let rewards = [ $"{defaultHack.Name} Hack" ; $"{defaultShield.Name} Shield" ] let embed = Embeds.getAchievementEmbed rewards "You completed the Training Dojo and collected loot." trainerAchievement diff --git a/DbService/DbService.fs b/DbService/DbService.fs index f717921..4bdfc79 100644 --- a/DbService/DbService.fs +++ b/DbService/DbService.fs @@ -35,7 +35,7 @@ let getPlayerEvents connStr (player : PlayerData) = |> Sql.query """ WITH usr AS (SELECT id FROM "user" WHERE discord_id = @did) SELECT event_type, success, is_instigator, item_id, cooldown, adversary_id, adversary_name, created_at - FROM player_event ,usr WHERE user_id = usr.id; + FROM player_event ,usr WHERE user_id = usr.id and created_at > NOW() at time zone 'utc' - INTERVAL '24 HOURS'; """ |> Sql.executeAsync (fun read -> match read.string "event_type" with