Fix bugs with redpill, cooldowns, and store

This commit is contained in:
Joseph Ferano 2022-01-24 03:53:14 +07:00
parent b501dfbb73
commit 2553d789d1
3 changed files with 48 additions and 36 deletions

View File

@ -9,6 +9,15 @@ open DSharpPlus.SlashCommands
open Degenz
open Degenz.Shared
let getTimeTillCooldownFinishes (timespan : TimeSpan) timestamp =
let timeRemaining = timespan - (DateTime.UtcNow - timestamp)
if timeRemaining.Hours > 0 then
$"{timeRemaining.Hours} hours"
elif timeRemaining.Minutes > 0 then
$"{timeRemaining.Minutes} minutes"
else
$"{timeRemaining.Seconds} seconds"
let checkForExistingHack attacker defenderId =
let updatedAttacks =
attacker.Attacks
@ -17,8 +26,8 @@ let checkForExistingHack attacker defenderId =
|> Array.tryFind (fun a -> a.Target.Id = defenderId)
|> function
| Some attack ->
let timeRemaining = TimeSpan.FromHours(24) - (DateTime.UtcNow - attack.Timestamp)
Error $"You can only hack the same target once every 24 hours, wait {timeRemaining.Seconds} seconds to attempt another hack on {attack.Target.Name}."
let cooldown = getTimeTillCooldownFinishes (TimeSpan.FromHours(24)) attack.Timestamp
Error $"You can only hack the same target once every 24 hours, wait {cooldown} to attempt another hack on {attack.Target.Name}."
| None ->
Ok updatedAttacks
@ -28,12 +37,12 @@ let checkIfHackHasCooldown hack updatedAttacks =
|> Array.tryFind (fun a -> a.HackType = hack)
|> function
| Some a -> a.Timestamp
| None -> DateTime.UtcNow
if DateTime.UtcNow - mostRecentHackAttack <= TimeSpan.FromMinutes(5) then
| None -> DateTime.MinValue
if DateTime.UtcNow - mostRecentHackAttack > TimeSpan.FromMinutes(5) then
Ok updatedAttacks
else
let timeRemaining = TimeSpan.FromMinutes(5) - (DateTime.UtcNow - mostRecentHackAttack)
Error $"You can only attack once a minute, wait {timeRemaining.Seconds} seconds to attack again."
let cooldown = getTimeTillCooldownFinishes (TimeSpan.FromMinutes(5)) mostRecentHackAttack
Error $"{hack} is currently on cooldown, wait {cooldown} to use it again."
let calculateDamage (hack: int) (shield: int) =
let hackClass = getClass hack
@ -43,7 +52,7 @@ let calculateDamage (hack: int) (shield: int) =
| h, p when h = p -> Weak
| _ -> Strong
let runHackerBattle attacker defender hack =
let runHackerBattle defender hack =
defender.Defenses
|> removeExpiredActions (TimeSpan.FromHours(6)) (fun (pro : Defense) -> pro.Timestamp)
|> Seq.toArray
@ -70,8 +79,7 @@ let successfulHack (event : ComponentInteractionCreateEventArgs) attacker defend
let builder = DiscordInteractionResponseBuilder()
builder.IsEphemeral <- true
builder.Content <- $"Successfully hacked {defender.Name} using {hack}! You just won {prize} GoodBoyTokenz!"
// TODO: Don't make this an Update
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> Async.AwaitTask
let builder = Embeds.eventSuccessfulHack event defender.DiscordId prize
@ -87,7 +95,7 @@ let failedHack (event : ComponentInteractionCreateEventArgs) attacker defender h
let prize = 2
builder.IsEphemeral <- true
builder.Content <- $"Hack failed! {defender.Name} was able to mount a successful defense! You lost {prize} GoodBoyTokenz!"
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> Async.AwaitTask
do! updateCombatants attacker defender hack -prize
@ -109,13 +117,16 @@ let attack (ctx : InteractionContext) (target : DiscordUser) =
let existingHack = checkForExistingHack attacker defender.DiscordId
match existingHack with
| Ok _ ->
let embed = Embeds.pickHack "Attack" attacker defender
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed)
|> Async.AwaitTask
let embed = Embeds.pickHack "Attack" attacker defender
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, embed)
|> Async.AwaitTask
| Error msg ->
let builder = DiscordInteractionResponseBuilder().WithContent(msg).AsEphemeral(true)
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> Async.AwaitTask
let builder =
DiscordInteractionResponseBuilder()
.WithContent(msg)
.AsEphemeral(true)
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> Async.AwaitTask
| None , _ -> do! notYetAHackerMsg ctx
| _ , None -> do! createSimpleResponseAsync "Your target is not connected to the network, they must join first by using the /redpill command" ctx
} |> Async.StartAsTask
@ -136,13 +147,16 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
|> Result.bind (checkIfHackHasCooldown hack)
|> function
| Ok _ ->
runHackerBattle attacker defender hack
runHackerBattle defender hack
|> function
| false -> successfulHack event attacker defender hack
| true -> failedHack event attacker defender hack
| Error msg ->
let builder = DiscordInteractionResponseBuilder()
event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder.WithContent(msg))
let builder =
DiscordInteractionResponseBuilder()
.WithContent(msg)
.AsEphemeral(true)
event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> Async.AwaitTask
| _ ->
let builder = DiscordInteractionResponseBuilder()
@ -201,19 +215,17 @@ let handleDefense (event : ComponentInteractionCreateEventArgs) =
let builder = DiscordInteractionResponseBuilder()
builder.IsEphemeral <- true
let timestamp = updatedDefenses |> Array.rev |> Array.head |> fun a -> a.Timestamp // This should be the next expiring timestamp
let timeRemaining = TimeSpan.FromMinutes(15) - (DateTime.UtcNow - timestamp)
let hours = if timeRemaining.Hours > 0 then $"{timeRemaining.Hours} hours and " else ""
builder.Content <- $"You are only allowed two shields at a time. Wait {hours}{timeRemaining.Minutes} minutes to add another shield"
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
let cooldown = getTimeTillCooldownFinishes (TimeSpan.FromHours(6)) timestamp
builder.Content <- $"You are only allowed two shields at a time. Wait {cooldown} minutes to add another shield"
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> Async.AwaitTask
do! DbService.updatePlayer <| { player with Defenses = updatedDefenses }
| true , _ ->
let builder = DiscordInteractionResponseBuilder()
builder.IsEphemeral <- true
let timestamp = updatedDefenses |> Array.find (fun d -> d.DefenseType = shield) |> fun a -> a.Timestamp
let timeRemaining = TimeSpan.FromMinutes(15) - (DateTime.UtcNow - timestamp)
let hours = if timeRemaining.Hours > 0 then $"{timeRemaining.Hours} hours and " else ""
builder.Content <- $"{shield} shield is already in use. Wait {hours}{timeRemaining.Minutes} minutes to use this shield again"
let cooldown = getTimeTillCooldownFinishes (TimeSpan.FromHours(6)) timestamp
builder.Content <- $"{shield} shield is already in use. Wait {cooldown} minutes to use this shield again"
do! event.Interaction.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|> Async.AwaitTask
do! DbService.updatePlayer <| { player with Defenses = updatedDefenses }

View File

@ -40,13 +40,13 @@ module Commands =
| Some _ -> async.Return false
| None ->
async {
do! newPlayer ctx.Member.Username ctx.Member.Id
do! newPlayer ctx.Member.DisplayName ctx.Member.Id
|> DbService.insertNewPlayer
for role in ctx.Guild.Roles do
if role.Value.Name = "Hacker" then
do! ctx.Member.GrantRoleAsync(role.Value)
|> Async.AwaitTask
// for role in ctx.Guild.Roles do
// if role.Value.Name = "Hacker" then
// do! ctx.Member.GrantRoleAsync(role.Value)
// |> Async.AwaitTask
return true
}
@ -64,10 +64,10 @@ module Commands =
let removeHackerRole (ctx : InteractionContext) =
async {
for role in ctx.Member.Roles do
if role.Name = "Hacker" then
do! ctx.Member.RevokeRoleAsync(role)
|> Async.AwaitTask
// for role in ctx.Member.Roles do
// if role.Name = "Hacker" then
// do! ctx.Member.RevokeRoleAsync(role)
// |> Async.AwaitTask
do! DbService.removePlayer ctx.Member.Id

View File

@ -148,7 +148,7 @@ let handleSellButtonEvents (_ : DiscordClient) (event : ComponentInteractionCrea
let itemName = split.[1]
match itemType with
| ItemType.Hack -> do! sellItem event updateHacks player player.Weapons ItemType.Hack itemName
| ItemType.Shield -> do! sellItem event updateShields player player.Shields ItemType.Hack itemName
| ItemType.Shield -> do! sellItem event updateShields player player.Shields ItemType.Shield itemName
| None ->
let builder = DiscordInteractionResponseBuilder()
builder.IsEphemeral <- true