Fix how we manage hack cooldowns

This commit is contained in:
Joseph Ferano 2022-02-02 22:27:22 +07:00
parent 87e0c063a8
commit d6888d5e4a
5 changed files with 44 additions and 28 deletions

View File

@ -16,15 +16,24 @@ let checkIfPlayerIsAttackingThemselves defender attacker =
| true -> Error "You think you're clever? You can't hack yourself, pal." | true -> Error "You think you're clever? You can't hack yourself, pal."
| false -> Ok attacker | false -> Ok attacker
let checkForExistingHack defenderId attacker = let checkForExistingTarget defenderId attacker =
attacker.Actions attacker.Actions
|> Player.removeExpiredActions
|> Player.getAttacksFlat |> Player.getAttacksFlat
|> Array.tryFind (fun (_,t,_) -> t.Id = defenderId) |> Array.tryFind (fun (_,t,_) -> t.Id = defenderId)
|> function |> function
| Some ( atk , target , _ ) -> | Some ( atk , target , _ ) ->
let cooldown = getTimeTillCooldownFinishes (TimeSpan.FromHours(2)) atk.Timestamp let cooldown = getTimeTillCooldownFinishes Player.SameTargetAttackCooldown atk.Timestamp
Error $"You can only hack the same target once every 2 hours, wait {cooldown} to attempt another hack on {target.Name}." Error $"You can only hack the same target once every {Player.SameTargetAttackCooldown.Hours} hours, wait {cooldown} to attempt another hack on {target.Name}."
| None -> Ok attacker
let checkHackForCooldown (hack : BattleItem) attacker =
attacker
|> Player.attacks
|> Array.tryFind (fun (act) -> act.ActionId = hack.Id)
|> function
| Some act ->
let cooldown = getTimeTillCooldownFinishes Player.SameTargetAttackCooldown act.Timestamp
Error $"{hack.Name} is currently on cooldown, wait {cooldown} to use it again."
| None -> Ok attacker | None -> Ok attacker
let checkIfHackHasCooldown hackId attacker = let checkIfHackHasCooldown hackId attacker =
@ -57,8 +66,9 @@ let calculateDamage (hack : BattleItem) (shield : BattleItem) =
else Weak else Weak
let runHackerBattle defender hack = let runHackerBattle defender hack =
Player.defenses defender defender
|> Player.removeExpiredActions |> Player.removeExpiredActions
|> Player.defenses
|> Array.map (fun dfn -> Armory.battleItems |> Array.find (fun w -> w.Id = dfn.ActionId)) |> Array.map (fun dfn -> Armory.battleItems |> Array.find (fun w -> w.Id = dfn.ActionId))
|> Array.map (calculateDamage (hack)) |> Array.map (calculateDamage (hack))
|> Array.contains Weak |> Array.contains Weak
@ -112,10 +122,12 @@ let attack (ctx : InteractionContext) (target : DiscordUser) =
let! defender = DbService.tryFindPlayer target.Id let! defender = DbService.tryFindPlayer target.Id
match defender with match defender with
| Some defender -> | Some defender ->
do! checkForExistingHack defender.DiscordId attacker do! attacker
|> Player.removeExpiredActions
|> checkForExistingTarget defender.DiscordId
>>= checkIfInventoryIsEmpty >>= checkIfInventoryIsEmpty
>>= (checkIfTargetHasMoney defender) >>= checkIfTargetHasMoney defender
>>= (checkIfPlayerIsAttackingThemselves defender) >>= checkIfPlayerIsAttackingThemselves defender
|> function |> function
| Ok _ -> | Ok _ ->
let embed = Embeds.pickHack "Attack" attacker defender let embed = Embeds.pickHack "Attack" attacker defender
@ -141,8 +153,10 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
match resultPlayer , resultTarget , true , resultId with match resultPlayer , resultTarget , true , resultId with
| Some attacker , Some defender , true , true -> | Some attacker , Some defender , true , true ->
do! checkForExistingHack defender.DiscordId attacker do! attacker
|> Result.bind (checkIfHackHasCooldown (int hack)) |> Player.removeExpiredActions
|> checkForExistingTarget defender.DiscordId
>>= (checkIfHackHasCooldown (int hack))
|> function |> function
| Ok _ -> | Ok _ ->
runHackerBattle defender (Armory.getItem (int hack)) runHackerBattle defender (Armory.getItem (int hack))
@ -185,7 +199,7 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
let! playerResult = DbService.tryFindPlayer event.User.Id let! playerResult = DbService.tryFindPlayer event.User.Id
match playerResult with match playerResult with
| Some player -> | Some player ->
let updatedDefenses = Player.defenses player |> Player.removeExpiredActions let updatedDefenses = player |> Player.removeExpiredActions |> Player.defenses
let alreadyUsedShield = updatedDefenses |> Array.exists (fun d -> d.ActionId = int shield) let alreadyUsedShield = updatedDefenses |> Array.exists (fun d -> d.ActionId = int shield)
match alreadyUsedShield , updatedDefenses.Length < 2 with match alreadyUsedShield , updatedDefenses.Length < 2 with

View File

@ -10,7 +10,7 @@
}, },
"Cost": 100, "Cost": 100,
"Power": 50, "Power": 50,
"Cooldown": 260 "Cooldown": 2
}, },
{ {
"Id": 1, "Id": 1,
@ -23,7 +23,7 @@
}, },
"Cost": 100, "Cost": 100,
"Power": 50, "Power": 50,
"Cooldown": 260 "Cooldown": 2
}, },
{ {
"Id": 2, "Id": 2,
@ -36,7 +36,7 @@
}, },
"Cost": 100, "Cost": 100,
"Power": 50, "Power": 50,
"Cooldown": 260 "Cooldown": 2
}, },
{ {
"Id": 6, "Id": 6,
@ -49,7 +49,7 @@
}, },
"Cost": 100, "Cost": 100,
"Power": 50, "Power": 50,
"Cooldown": 260 "Cooldown": 240
}, },
{ {
"Id": 7, "Id": 7,
@ -62,7 +62,7 @@
}, },
"Cost": 100, "Cost": 100,
"Power": 50, "Power": 50,
"Cooldown": 260 "Cooldown": 240
}, },
{ {
"Id": 8, "Id": 8,
@ -75,6 +75,6 @@
}, },
"Cost": 100, "Cost": 100,
"Power": 50, "Power": 50,
"Cooldown": 260 "Cooldown": 240
} }
] ]

View File

@ -1,10 +1,7 @@
module Degenz.PlayerInteractions module Degenz.PlayerInteractions
open System.Threading.Tasks open System.Threading.Tasks
open DSharpPlus.Entities
open DSharpPlus
open DSharpPlus.SlashCommands open DSharpPlus.SlashCommands
open Degenz.Store
open Degenz.Types open Degenz.Types
module Commands = module Commands =

View File

@ -87,8 +87,7 @@ let handleSellButtonEvents (_ : DiscordClient) (event : ComponentInteractionCrea
let status (ctx : InteractionContext) = let status (ctx : InteractionContext) =
Game.executePlayerInteraction ctx (fun player -> async { Game.executePlayerInteraction ctx (fun player -> async {
let updatedActions = Player.removeExpiredActions player.Actions let updatedPlayer = Player.removeExpiredActions player
let updatedPlayer = { player with Actions = updatedActions }
let builder = DiscordInteractionResponseBuilder() let builder = DiscordInteractionResponseBuilder()
let embed = DiscordEmbedBuilder() let embed = DiscordEmbedBuilder()
embed.AddField("Arsenal", Messaging.statusFormat updatedPlayer) |> ignore embed.AddField("Arsenal", Messaging.statusFormat updatedPlayer) |> ignore

View File

@ -84,6 +84,7 @@ module Armory =
let getItem itemId = battleItems |> Array.find (fun w -> w.Id = itemId) let getItem itemId = battleItems |> Array.find (fun w -> w.Id = itemId)
module Player = module Player =
let SameTargetAttackCooldown = TimeSpan.FromHours(2)
let hacks player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Hack) let hacks player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Hack)
let shields player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Shield) let shields player = player.Arsenal |> Array.filter (fun bi -> bi.Type = Shield)
let attacks player = let attacks player =
@ -91,12 +92,17 @@ module Player =
|> Array.filter (fun act -> match act.Type with Attack _ -> true | _ -> false) |> Array.filter (fun act -> match act.Type with Attack _ -> true | _ -> false)
let defenses player = player.Actions |> Array.filter (fun act -> match act.Type with Defense -> true | _ -> false) let defenses player = player.Actions |> Array.filter (fun act -> match act.Type with Defense -> true | _ -> false)
// TODO: I have to fix this, this will remove hacks before the single target cooldown expires let removeExpiredActions player =
let removeExpiredActions actions = let actions =
actions player.Actions
|> Array.filter (fun (act : Action) -> |> Array.filter (fun (act : Action) ->
let item = Armory.battleItems |> Array.find (fun w -> w.Id = act.ActionId) match act.Type with
// So the player doesnt attack the same player so many times in a row
| Attack _ -> DateTime.UtcNow - act.Timestamp < SameTargetAttackCooldown
| Defense ->
let item = Armory.getItem act.ActionId
DateTime.UtcNow - act.Timestamp < TimeSpan.FromMinutes(int item.Cooldown)) DateTime.UtcNow - act.Timestamp < TimeSpan.FromMinutes(int item.Cooldown))
{ player with Actions = actions }
let modifyBank player amount = { player with Bank = max (player.Bank + amount) 0<GBT> } let modifyBank player amount = { player with Bank = max (player.Bank + amount) 0<GBT> }