Fixed bug with defending and small changes to gameplay
This commit is contained in:
parent
162f6af03f
commit
5ab49e674e
@ -23,7 +23,7 @@ let attack (ctx : InteractionContext) (target : DiscordUser) =
|
||||
| Some attacker , Some defender ->
|
||||
let updatedAttacks =
|
||||
attacker.Attacks
|
||||
|> removeExpiredActions (TimeSpan.FromMinutes(5)) (fun (atk : Attack) -> atk.Timestamp)
|
||||
|> removeExpiredActions (TimeSpan.FromMinutes(15)) (fun (atk : Attack) -> atk.Timestamp)
|
||||
do! DbService.updateAttacks attacker.DiscordId updatedAttacks
|
||||
if updatedAttacks.Length < 2 then
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
@ -61,11 +61,11 @@ let defend (ctx : InteractionContext) =
|
||||
let! player = DbService.tryFindPlayer ctx.Member.Id
|
||||
match player with
|
||||
| Some player ->
|
||||
let updatedDefenses = removeExpiredActions (TimeSpan.FromMinutes(60)) (fun (pro : Defense) -> pro.Timestamp) player.Defenses
|
||||
let updatedDefenses = removeExpiredActions (TimeSpan.FromHours(24)) (fun (pro : Defense) -> pro.Timestamp) player.Defenses
|
||||
do! DbService.updatePlayer <| { player with Defenses = updatedDefenses }
|
||||
if updatedDefenses.Length < 2 then
|
||||
if updatedDefenses.Length < 3 then
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.AddEmbed (constructEmbed "Pick a defense to mount for a duration of time") |> ignore
|
||||
builder.AddEmbed (constructEmbed "Pick a defense to mount for 24 hours") |> ignore
|
||||
|
||||
constructButtons "Defend" (string player.DiscordId) player.Shields
|
||||
|> Seq.cast<DiscordComponent>
|
||||
@ -80,7 +80,8 @@ let defend (ctx : InteractionContext) =
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
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)
|
||||
builder.Content <- $"Cannot add new defense, please wait {timeRemaining.Minutes} minutes and {timeRemaining.Seconds} seconds to add another defense"
|
||||
// TODO: Make this handle hours and minutes
|
||||
builder.Content <- $"Cannot add new defense, please wait {timeRemaining.Hours} hours and {timeRemaining.Minutes} minutes to add another defense"
|
||||
|
||||
builder.AsEphemeral true |> ignore
|
||||
|
||||
@ -101,43 +102,46 @@ let handleAttack (event : ComponentInteractionCreateEventArgs) =
|
||||
let! resultTarget = DbService.tryFindPlayer targetId
|
||||
match resultPlayer , resultTarget , resultHack , resultId with
|
||||
| Some player , Some target , true , true ->
|
||||
let updatedDefenses = removeExpiredActions (TimeSpan.FromHours(24)) (fun (p : Defense) -> p.Timestamp) target.Defenses
|
||||
do! DbService.updatePlayer <| { player with Defenses = updatedDefenses }
|
||||
let wasSuccessfulHack =
|
||||
target.Defenses
|
||||
updatedDefenses
|
||||
|> Seq.toArray
|
||||
|> Array.map (fun dfn -> int dfn.DefenseType)
|
||||
|> Array.map (calculateDamage weapon)
|
||||
|> Array.contains Weak
|
||||
match wasSuccessfulHack with
|
||||
| false ->
|
||||
let prize = 0.1726f
|
||||
let prize = 1.337f // LEET
|
||||
let attack = { HackType = enum<Weapon>(weapon) ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
||||
do! DbService.updatePlayer <| updatePlayer prize attack player
|
||||
do! DbService.updatePlayer { target with Bank = MathF.Max(target.Bank - prize, 0f)}
|
||||
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.IsEphemeral <- true
|
||||
builder.Content <- $"Successfully hacked {split.[3]} using {weapon}! You just won {prize} genz!"
|
||||
builder.Content <- $"Successfully hacked {split.[3]} using {weapon}! You just won {prize} GoodBoyTokenz!"
|
||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let builder = DiscordMessageBuilder()
|
||||
builder.WithContent($"{event.User.Username} successfully hacked <@{targetId}>!") |> ignore
|
||||
builder.WithContent($"{event.User.Username} successfully hacked <@{targetId}> for a total of {prize} GoodBoyTokenz") |> ignore
|
||||
let channel = (event.Guild.GetChannel(battleChannel))
|
||||
do! channel.SendMessageAsync(builder)
|
||||
|> Async.AwaitTask
|
||||
|> Async.Ignore
|
||||
| true ->
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
let loss = -0.0623f
|
||||
let prize = 0.0623f
|
||||
builder.IsEphemeral <- true
|
||||
builder.Content <- $"Hack failed! {split.[3]} was able to mount a successful defense! You lost {loss} genz!"
|
||||
builder.Content <- $"Hack failed! {split.[3]} was able to mount a successful defense! You lost {prize} GoodBoyTokenz!"
|
||||
do! event.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, builder)
|
||||
|> Async.AwaitTask
|
||||
|
||||
let attack = { HackType = enum<Weapon>(weapon) ; Timestamp = DateTime.UtcNow ; Target = { Id = targetId ; Name = split.[3] } }
|
||||
do! DbService.updatePlayer <| updatePlayer loss attack player
|
||||
do! DbService.updatePlayer <| updatePlayer -prize attack player
|
||||
|
||||
let builder = DiscordMessageBuilder()
|
||||
builder.WithContent($"{event.User.Username} failed to hack <@{targetId}>!") |> ignore
|
||||
builder.WithContent($"Hacking attempt failed! <@{targetId}> defended hack from {event.User} and took {prize} from them! ") |> ignore
|
||||
let channel = (event.Guild.GetChannel(battleChannel))
|
||||
do! channel.SendMessageAsync(builder)
|
||||
|> Async.AwaitTask
|
||||
|
@ -94,6 +94,9 @@ module Commands =
|
||||
let! player = DbService.tryFindPlayer ctx.Member.Id
|
||||
match player with
|
||||
| Some p ->
|
||||
let updatedAttacks = p.Attacks |> removeExpiredActions (TimeSpan.FromMinutes(15)) (fun (atk : Attack) -> atk.Timestamp)
|
||||
let updatedDefenses = p.Defenses |> removeExpiredActions (TimeSpan.FromHours(24)) (fun (p : Defense) -> p.Timestamp)
|
||||
do! DbService.updatePlayer <| { p with Attacks = updatedAttacks ; Defenses = updatedDefenses }
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.IsEphemeral <- true
|
||||
builder.Content <- statusFormat p
|
||||
|
@ -26,55 +26,56 @@ type Shield =
|
||||
| Sanitation = 5
|
||||
| Cypher = 3
|
||||
|
||||
let getClass = function
|
||||
| 0 | 1 -> Network
|
||||
| 2 | 3 -> Exploit
|
||||
| 4 | _ -> Penetration
|
||||
let getClass =
|
||||
function
|
||||
| 0
|
||||
| 1 -> Network
|
||||
| 2
|
||||
| 3 -> Exploit
|
||||
| 4
|
||||
| _ -> Penetration
|
||||
|
||||
type HackResult =
|
||||
| Strong
|
||||
| Weak
|
||||
|
||||
[<CLIMutable>]
|
||||
type DiscordPlayer = {
|
||||
Id : uint64
|
||||
Name : string
|
||||
}
|
||||
type DiscordPlayer = { Id: uint64; Name: string }
|
||||
|
||||
[<CLIMutable>]
|
||||
type Attack = {
|
||||
HackType : Weapon
|
||||
Target : DiscordPlayer
|
||||
Timestamp : DateTime
|
||||
}
|
||||
type Attack =
|
||||
{ HackType: Weapon
|
||||
Target: DiscordPlayer
|
||||
Timestamp: DateTime }
|
||||
|
||||
[<CLIMutable>]
|
||||
type Defense = {
|
||||
DefenseType : Shield
|
||||
Timestamp : DateTime
|
||||
}
|
||||
type Defense =
|
||||
{ DefenseType: Shield
|
||||
Timestamp: DateTime }
|
||||
|
||||
[<CLIMutable>]
|
||||
type Player = {
|
||||
DiscordId : uint64
|
||||
Name : string
|
||||
Weapons : Weapon array
|
||||
Shields : Shield array
|
||||
Attacks : Attack array
|
||||
Defenses : Defense array
|
||||
Bank : single
|
||||
}
|
||||
type Player =
|
||||
{ DiscordId: uint64
|
||||
Name: string
|
||||
Weapons: Weapon array
|
||||
Shields: Shield array
|
||||
Attacks: Attack array
|
||||
Defenses: Defense array
|
||||
Bank: single }
|
||||
|
||||
let createSimpleResponseAsync msg (ctx : InteractionContext) =
|
||||
let createSimpleResponseAsync msg (ctx: InteractionContext) =
|
||||
async {
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.Content <- msg
|
||||
builder.AsEphemeral true |> ignore
|
||||
do! ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||
|
||||
do!
|
||||
ctx.CreateResponseAsync(InteractionResponseType.ChannelMessageWithSource, builder)
|
||||
|> Async.AwaitTask
|
||||
}
|
||||
|
||||
let notYetAHackerMsg = createSimpleResponseAsync "You are not currently a hacker, first use the /redpill command to become one"
|
||||
let notYetAHackerMsg =
|
||||
createSimpleResponseAsync "You are not currently a hacker, first use the /redpill command to become one"
|
||||
|
||||
let hackDescription = ""
|
||||
|
||||
@ -85,20 +86,12 @@ Active Hacks: {player.Attacks |> Array.toList}
|
||||
Active Defenses: {player.Defenses |> Array.toList}
|
||||
Bank: {player.Bank}"
|
||||
|
||||
let constructButtons (actionType : string) (playerInfo : string) (weapons : 'a array) =
|
||||
let constructButtons (actionType: string) (playerInfo: string) (weapons: 'a array) =
|
||||
weapons
|
||||
|> Seq.map (fun hack ->
|
||||
DiscordButtonComponent(
|
||||
ButtonStyle.Primary,
|
||||
$"{actionType}-{hack}-{playerInfo}",
|
||||
$"{hack}"))
|
||||
|> Seq.map (fun hack -> DiscordButtonComponent(ButtonStyle.Primary, $"{actionType}-{hack}-{playerInfo}", $"{hack}"))
|
||||
|
||||
let removeExpiredActions timespan (timestamp : 'a -> DateTime) actions =
|
||||
actions
|
||||
|> Array.filter (fun act ->
|
||||
if DateTime.UtcNow - (timestamp act) < timespan
|
||||
then true
|
||||
else false)
|
||||
let removeExpiredActions timespan (timestamp: 'a -> DateTime) actions =
|
||||
actions |> Array.filter (fun act -> DateTime.UtcNow - (timestamp act) < timespan)
|
||||
|
||||
let constructEmbed message =
|
||||
let builder = DiscordEmbedBuilder()
|
||||
@ -111,10 +104,10 @@ let constructEmbed message =
|
||||
builder.Author <- author
|
||||
builder.Build()
|
||||
|
||||
let calculateDamage (hack : int) (shield : int) =
|
||||
let calculateDamage (hack: int) (shield: int) =
|
||||
let hackClass = getClass hack
|
||||
let protectionClass = getClass shield
|
||||
match hackClass , protectionClass with
|
||||
| h , p when h = p -> Weak
|
||||
| _ -> Strong
|
||||
|
||||
match hackClass, protectionClass with
|
||||
| h, p when h = p -> Weak
|
||||
| _ -> Strong
|
||||
|
Loading…
x
Reference in New Issue
Block a user