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

View File

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

View File

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

View File

@ -87,8 +87,7 @@ let handleSellButtonEvents (_ : DiscordClient) (event : ComponentInteractionCrea
let status (ctx : InteractionContext) =
Game.executePlayerInteraction ctx (fun player -> async {
let updatedActions = Player.removeExpiredActions player.Actions
let updatedPlayer = { player with Actions = updatedActions }
let updatedPlayer = Player.removeExpiredActions player
let builder = DiscordInteractionResponseBuilder()
let embed = DiscordEmbedBuilder()
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)
module Player =
let SameTargetAttackCooldown = TimeSpan.FromHours(2)
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 attacks player =
@ -91,12 +92,17 @@ module Player =
|> 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)
// TODO: I have to fix this, this will remove hacks before the single target cooldown expires
let removeExpiredActions actions =
actions
|> Array.filter (fun (act : Action) ->
let item = Armory.battleItems |> Array.find (fun w -> w.Id = act.ActionId)
DateTime.UtcNow - act.Timestamp < TimeSpan.FromMinutes(int item.Cooldown))
let removeExpiredActions player =
let actions =
player.Actions
|> Array.filter (fun (act : Action) ->
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))
{ player with Actions = actions }
let modifyBank player amount = { player with Bank = max (player.Bank + amount) 0<GBT> }