Changes and fixes to attributes
This commit is contained in:
parent
881fd12aa9
commit
e51223df88
@ -121,7 +121,7 @@ let getBuyItemsEmbed (player : PlayerData) (itemType : ItemType) (store : Item a
|
|||||||
.WithThumbnail(getShieldIcon (enum<ShieldId>(item.Id)))
|
.WithThumbnail(getShieldIcon (enum<ShieldId>(item.Id)))
|
||||||
|> ignore
|
|> ignore
|
||||||
embed
|
embed
|
||||||
.AddField("Cost 💰", $"{item.Price} $GBT", true)
|
.AddField("Price 💰", $"{item.Price} $GBT", true)
|
||||||
.WithTitle($"{item.Name}")
|
.WithTitle($"{item.Name}")
|
||||||
|> ignore
|
|> ignore
|
||||||
let button =
|
let button =
|
||||||
|
18
Bot/Game.fs
18
Bot/Game.fs
@ -68,10 +68,10 @@ module Player =
|
|||||||
let getShields (player : PlayerData) = getItems ItemType.Shield player
|
let getShields (player : PlayerData) = getItems ItemType.Shield player
|
||||||
let getHackEvents player =
|
let getHackEvents player =
|
||||||
player.Events
|
player.Events
|
||||||
|> Array.filter (fun act -> match act.Type with PlayerEventType.Hacking -> true | _ -> false || act.ItemId < 12)
|
|> Array.filter (fun act -> match act.Type with PlayerEventType.Hacking -> true | _ -> false && act.ItemId < 12)
|
||||||
let getShieldEvents player =
|
let getShieldEvents player =
|
||||||
player.Events
|
player.Events
|
||||||
|> Array.filter (fun act -> match act.Type with PlayerEventType.Shielding -> true | _ -> false || act.ItemId < 12)
|
|> Array.filter (fun act -> match act.Type with PlayerEventType.Shielding -> true | _ -> false && act.ItemId < 12)
|
||||||
|
|
||||||
// TODO: This parameter is a result of putting the cooldown on the attack side. Put the cooldown on the defender
|
// TODO: This parameter is a result of putting the cooldown on the attack side. Put the cooldown on the defender
|
||||||
// side and only check if it's the same target, we need to refactor Actions
|
// side and only check if it's the same target, we need to refactor Actions
|
||||||
@ -106,28 +106,22 @@ module Arsenal =
|
|||||||
let actionFormat (actions : PlayerEvent array) =
|
let actionFormat (actions : PlayerEvent array) =
|
||||||
match actions with
|
match actions with
|
||||||
| [||] -> "None"
|
| [||] -> "None"
|
||||||
| _ ->
|
| _ -> actions
|
||||||
let hacks , defenses =
|
|
||||||
actions
|
|
||||||
|> Array.filter (fun act -> act.ItemId < 12)
|
|
||||||
|> Array.partition (fun act -> match act.Type with PlayerEventType.Hacking -> true | _ -> false)
|
|
||||||
let hacks = hacks |> Array.take (min hacks.Length 10)
|
|
||||||
hacks
|
|
||||||
|> Array.append defenses
|
|
||||||
|> Array.map (fun act ->
|
|> Array.map (fun act ->
|
||||||
let item = Armory.getItem act.ItemId
|
let item = Armory.getItem act.ItemId
|
||||||
match act.Type with
|
match act.Type with
|
||||||
| PlayerEventType.Hacking ->
|
| PlayerEventType.Hacking ->
|
||||||
let cooldown = Messaging.getTimeText false Game.SameTargetAttackCooldown act.Timestamp
|
let cooldown = Messaging.getTimeText false Game.SameTargetAttackCooldown act.Timestamp
|
||||||
$"Hacked {act.Adversary.Name} {cooldown} ago"
|
$"Hacked {act.Adversary.Name} with {item.Name} {cooldown} ago"
|
||||||
| _ ->
|
| _ ->
|
||||||
let cooldown = Messaging.getTimeText true (System.TimeSpan.FromMinutes(int item.Cooldown)) act.Timestamp
|
let cooldown = Messaging.getTimeText true (System.TimeSpan.FromMinutes(int item.Cooldown)) act.Timestamp
|
||||||
$"{item.Name} Shield active for {cooldown}")
|
$"{item.Name} Shield active for {cooldown}")
|
||||||
|> String.concat "\n"
|
|> String.concat "\n"
|
||||||
|
|
||||||
let statusFormat p =
|
let statusFormat p =
|
||||||
|
let hacks = Player.getHackEvents p
|
||||||
$"**Hacks:** {Player.getHacks p |> battleItemFormat}\n
|
$"**Hacks:** {Player.getHacks p |> battleItemFormat}\n
|
||||||
**Shields:** {Player.getShields p |> battleItemFormat}\n
|
**Shields:** {Player.getShields p |> battleItemFormat}\n
|
||||||
**Hack Attacks:**\n{Player.getHackEvents p |> actionFormat}\n
|
**Hack Attacks:**\n{ hacks |> Array.take (min hacks.Length 10) |> actionFormat}\n
|
||||||
**Active Shields:**\n{Player.getShieldEvents p |> actionFormat}"
|
**Active Shields:**\n{Player.getShieldEvents p |> actionFormat}"
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ type HackerGame() =
|
|||||||
|
|
||||||
[<SlashCommand("hack", "Send a hack attack to another player")>]
|
[<SlashCommand("hack", "Send a hack attack to another player")>]
|
||||||
member this.AttackCommand (ctx : InteractionContext, [<Option("target", "The player you want to hack")>] target : DiscordUser) =
|
member this.AttackCommand (ctx : InteractionContext, [<Option("target", "The player you want to hack")>] target : DiscordUser) =
|
||||||
enforceChannels (DiscordInteractionContext ctx) (Trainer.attack target) (attack target)
|
enforceChannels (DiscordInteractionContext ctx) (Trainer.hack target) (attack target)
|
||||||
|
|
||||||
[<SlashCommand("shield", "Create a passive shield that will protect you for a certain time")>]
|
[<SlashCommand("shield", "Create a passive shield that will protect you for a certain time")>]
|
||||||
member this.ShieldCommand (ctx : InteractionContext) =
|
member this.ShieldCommand (ctx : InteractionContext) =
|
||||||
|
@ -3,48 +3,84 @@
|
|||||||
"Id": 0,
|
"Id": 0,
|
||||||
"Name": "Virus",
|
"Name": "Virus",
|
||||||
"Type": 0,
|
"Type": 0,
|
||||||
"Cost": 50,
|
"Price": 0,
|
||||||
"Power": 50,
|
"Power": 10,
|
||||||
"Cooldown": 2
|
"Cooldown": 2,
|
||||||
|
"Attributes": {
|
||||||
|
"Sell": false,
|
||||||
|
"Buy": false,
|
||||||
|
"Consume": false,
|
||||||
|
"Drop": false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 1,
|
"Id": 1,
|
||||||
"Name": "RemoteAccess",
|
"Name": "RemoteAccess",
|
||||||
"Type": 0,
|
"Type": 0,
|
||||||
"Cost": 50,
|
"Price": 500,
|
||||||
"Power": 50,
|
"Power": 50,
|
||||||
"Cooldown": 2
|
"Cooldown": 2,
|
||||||
|
"Attributes": {
|
||||||
|
"Sell": true,
|
||||||
|
"Buy": true,
|
||||||
|
"Consume": false,
|
||||||
|
"Drop": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 2,
|
"Id": 2,
|
||||||
"Name": "Worm",
|
"Name": "Worm",
|
||||||
"Type": 0,
|
"Type": 0,
|
||||||
"Cost": 50,
|
"Price": 5000,
|
||||||
"Power": 50,
|
"Power": 80,
|
||||||
"Cooldown": 2
|
"Cooldown": 2,
|
||||||
|
"Attributes": {
|
||||||
|
"Sell": true,
|
||||||
|
"Buy": true,
|
||||||
|
"Consume": false,
|
||||||
|
"Drop": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 6,
|
"Id": 6,
|
||||||
"Name": "Firewall",
|
"Name": "Firewall",
|
||||||
"Type": 1,
|
"Type": 1,
|
||||||
"Cost": 50,
|
"Price": 0,
|
||||||
"Power": 50,
|
"Power": 10,
|
||||||
"Cooldown": 600
|
"Cooldown": 600,
|
||||||
|
"Attributes": {
|
||||||
|
"Sell": false,
|
||||||
|
"Buy": false,
|
||||||
|
"Consume": false,
|
||||||
|
"Drop": false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 8,
|
"Id": 8,
|
||||||
"Name": "Cypher",
|
"Name": "Cypher",
|
||||||
"Type": 1,
|
"Type": 1,
|
||||||
"Cost": 50,
|
"Price": 500,
|
||||||
"Power": 50,
|
"Power": 50,
|
||||||
"Cooldown": 600
|
"Cooldown": 600,
|
||||||
|
"Attributes": {
|
||||||
|
"Sell": true,
|
||||||
|
"Buy": true,
|
||||||
|
"Consume": false,
|
||||||
|
"Drop": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Id": 7,
|
"Id": 7,
|
||||||
"Name": "Encryption",
|
"Name": "Encryption",
|
||||||
"Type": 1,
|
"Type": 1,
|
||||||
"Cost": 50,
|
"Price": 5000,
|
||||||
"Power": 50,
|
"Power": 80,
|
||||||
"Cooldown": 600
|
"Cooldown": 600,
|
||||||
|
"Attributes": {
|
||||||
|
"Sell": true,
|
||||||
|
"Buy": true,
|
||||||
|
"Consume": false,
|
||||||
|
"Drop": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -168,8 +168,6 @@ let handleSteal (ctx : IDiscordContext) =
|
|||||||
let stole = { ItemId = -1 ; Type = PlayerEventType.Steal ; Result = PlayerEventResult.Positive ; Adversary = dp ; Timestamp = DateTime.UtcNow }
|
let stole = { ItemId = -1 ; Type = PlayerEventType.Steal ; Result = PlayerEventResult.Positive ; Adversary = dp ; Timestamp = DateTime.UtcNow }
|
||||||
let actions = player |> Player.removeExpiredActions false |> fun p -> Array.append [| stole |] p.Events
|
let actions = player |> Player.removeExpiredActions false |> fun p -> Array.append [| stole |] p.Events
|
||||||
do! DbService.updatePlayer { player with Bank = player.Bank + prize ; XP = player.XP + xp ; Events = actions }
|
do! DbService.updatePlayer { player with Bank = player.Bank + prize ; XP = player.XP + xp ; Events = actions }
|
||||||
let newLevel = XP.getLevel (player.XP + xp)
|
|
||||||
// if XP.getLevel player.XP < newLevel then
|
|
||||||
do! Async.Sleep 2000
|
do! Async.Sleep 2000
|
||||||
do! ctx.FollowUp (XP.getRewardsEmbed 1 player) |> Async.AwaitTask
|
do! ctx.FollowUp (XP.getRewardsEmbed 1 player) |> Async.AwaitTask
|
||||||
| false , false ->
|
| false , false ->
|
||||||
|
163
Bot/Trainer.fs
163
Bot/Trainer.fs
@ -1,16 +1,29 @@
|
|||||||
module Degenz.Trainer
|
module Degenz.Trainer
|
||||||
|
|
||||||
open System.Text
|
open System.Text
|
||||||
|
open System.Threading.Tasks
|
||||||
open DSharpPlus
|
open DSharpPlus
|
||||||
open DSharpPlus.Entities
|
open DSharpPlus.Entities
|
||||||
open DSharpPlus.EventArgs
|
|
||||||
open Degenz.Types
|
open Degenz.Types
|
||||||
open Degenz.Messaging
|
open Degenz.Messaging
|
||||||
|
|
||||||
let trainerAchievement = "FINISHED_TRAINER"
|
let trainerAchievement = "FINISHED_TRAINER"
|
||||||
|
let Sensei = { Id = GuildEnvironment.botIdHackerBattle ; Name = "Sensei" }
|
||||||
let defaultHack = Armory.battleItems |> Array.find (fun i -> i.Id = int HackId.Virus)
|
let defaultHack = Armory.battleItems |> Array.find (fun i -> i.Id = int HackId.Virus)
|
||||||
let defaultShield = Armory.battleItems |> Array.find (fun i -> i.Id = int ShieldId.Encryption)
|
let defaultShield = Armory.battleItems |> Array.find (fun i -> i.Id = int ShieldId.Firewall)
|
||||||
|
|
||||||
|
let TrainerEvents = [|
|
||||||
|
{ PlayerEvent.Timestamp = System.DateTime.UtcNow
|
||||||
|
PlayerEvent.Adversary = Sensei
|
||||||
|
PlayerEvent.Type = PlayerEventType.Hacking
|
||||||
|
PlayerEvent.Result = PlayerEventResult.Positive
|
||||||
|
PlayerEvent.ItemId = defaultHack.Id }
|
||||||
|
{ PlayerEvent.Timestamp = System.DateTime.UtcNow
|
||||||
|
PlayerEvent.Adversary = DiscordPlayer.empty
|
||||||
|
PlayerEvent.Type = PlayerEventType.Shielding
|
||||||
|
PlayerEvent.Result = PlayerEventResult.Positive
|
||||||
|
PlayerEvent.ItemId = defaultShield.Id }
|
||||||
|
|]
|
||||||
|
|
||||||
let sendInitialEmbed (client : DiscordClient) =
|
let sendInitialEmbed (client : DiscordClient) =
|
||||||
async {
|
async {
|
||||||
@ -31,41 +44,30 @@ let sendInitialEmbed (client : DiscordClient) =
|
|||||||
|
|
||||||
let handleTrainerStep1 (ctx : IDiscordContext) =
|
let handleTrainerStep1 (ctx : IDiscordContext) =
|
||||||
Game.executePlayerAction ctx (fun player -> async {
|
Game.executePlayerAction ctx (fun player -> async {
|
||||||
let shieldMessage , weaponName =
|
|
||||||
if Player.getShields player |> Array.isEmpty
|
|
||||||
then $"You do not have any Shields in your arsenal, take the `{defaultShield.Name}` shield, you can use it for now.\n\n" , defaultShield.Name
|
|
||||||
else
|
|
||||||
let name = Player.getShields player |> Array.tryHead |> Option.defaultValue defaultShield |> fun w -> w.Name
|
|
||||||
$"Looks like you have `{name}` in your arsenal… 👀\n\n" , name
|
|
||||||
|
|
||||||
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee)
|
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee)
|
||||||
do! ctx.GetDiscordMember().GrantRoleAsync(role)
|
do! ctx.GetDiscordMember().GrantRoleAsync(role)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|
|
||||||
do! sendFollowUpMessage ctx
|
do! sendFollowUpMessage ctx
|
||||||
("Beautopia© is a dangerous place... quick, put up a SHIELD 🛡 before another Degen hacks you, and steals your 💰$GBT.\n\n"
|
("Beautopia© is a dangerous place... quick, put up a SHIELD 🛡 before another Degen hacks you, and steals your 💰$GBT.\n\n"
|
||||||
+ shieldMessage
|
|
||||||
+ "To enable it, you need to run the `/shield` slash command.\n\n"
|
+ "To enable it, you need to run the `/shield` slash command.\n\n"
|
||||||
+ $"Type the `/shield` command now, then select - `{weaponName}`\n")
|
+ $"Type the `/shield` command now, then select - `{defaultShield.Name}`\n")
|
||||||
})
|
})
|
||||||
|
|
||||||
let defend (ctx : IDiscordContext) =
|
let defend (ctx : IDiscordContext) =
|
||||||
Game.executePlayerAction ctx (fun player -> async {
|
async {
|
||||||
let playerWithShields =
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
match Player.getShields player with
|
builder.IsEphemeral <- true
|
||||||
| [||] -> { player with Inventory = [| defaultShield |] }
|
builder.Content <- "Content"
|
||||||
| _ -> player
|
do! ctx.Respond InteractionResponseType.DeferredChannelMessageWithSource builder |> Async.AwaitTask
|
||||||
|
let embed = Embeds.pickDefense "Trainer-2" { PlayerData.empty with Inventory = [| defaultShield |] } true
|
||||||
let embed = Embeds.pickDefense "Trainer-2" playerWithShields true
|
|
||||||
|
|
||||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||||
})
|
} |> Async.StartAsTask :> Task
|
||||||
|
|
||||||
let handleDefenseMsg shieldId hackId = {
|
let handleDefenseMsg hackId = {
|
||||||
ButtonId = "Trainer-3"
|
ButtonId = "Trainer-3"
|
||||||
ButtonText = "Got it"
|
ButtonText = "Got it"
|
||||||
Message = "🎉 Congratulations you successfully defended my hack!\n\n"
|
Message = $"🎉 Congratulations you successfully defended my {hackId} hack!\n\n"
|
||||||
+ $"The `{shieldId}` shield is strong against the `{hackId}` hack, so make sure to have multiple shields up to protect from multiple attacks..."
|
|
||||||
+ "Shields only protect you for a LIMITED TIME, so remember to keep them mounted at all times, or risk getting hacked!"
|
+ "Shields only protect you for a LIMITED TIME, so remember to keep them mounted at all times, or risk getting hacked!"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,41 +80,32 @@ let handleDefense (ctx : IDiscordContext) =
|
|||||||
let embed = Embeds.responseCreatedShield shield
|
let embed = Embeds.responseCreatedShield shield
|
||||||
do! ctx.FollowUp embed |> Async.AwaitTask
|
do! ctx.FollowUp embed |> Async.AwaitTask
|
||||||
do! Async.Sleep 4000
|
do! Async.Sleep 4000
|
||||||
do! sendMessage' $"Ok, good, let me make sure that worked.\n\nI'll try to **hack** you now with **VIRUS**"
|
do! sendMessage' $"Ok, good, let me make sure that worked.\n\nI'll try to **hack** you now with **{defaultHack.Name}**"
|
||||||
do! Async.Sleep 5000
|
do! Async.Sleep 5000
|
||||||
do! sendMessage' $"❌ HACKING FAILED!\n\n{player.Name} defended hack from <@{GuildEnvironment.botIdHackerBattle}>!"
|
do! sendMessage' $"❌ HACKING FAILED!\n\n{player.Name} defended hack from <@{Sensei.Id}>!"
|
||||||
do! Async.Sleep 4000
|
do! Async.Sleep 4000
|
||||||
do! sendFollowUpMessageWithButton ctx (handleDefenseMsg shieldId "VIRUS")
|
do! sendFollowUpMessageWithButton ctx (handleDefenseMsg defaultHack.Name)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
let handleTrainerStep3 (ctx : IDiscordContext) =
|
let handleTrainerStep3 (ctx : IDiscordContext) =
|
||||||
Game.executePlayerAction ctx (fun player -> async {
|
async {
|
||||||
let hackMessage , weaponName =
|
let builder = DiscordInteractionResponseBuilder()
|
||||||
if Player.getHacks player |> Array.isEmpty
|
builder.IsEphemeral <- true
|
||||||
then $"You do not have any Hacks in your arsenal, take this `{defaultHack.Name}`, you can use it for now.\n\n" , defaultHack.Name
|
builder.Content <- "Content"
|
||||||
else
|
do! ctx.Respond InteractionResponseType.DeferredChannelMessageWithSource builder |> Async.AwaitTask
|
||||||
let name = Player.getHacks player |> Array.tryHead |> Option.defaultValue defaultHack |> fun w -> w.Name
|
|
||||||
$"Looks like you have `{name}` in your arsenal...\n\n" , name
|
|
||||||
|
|
||||||
do! sendFollowUpMessage ctx
|
do! sendFollowUpMessage ctx
|
||||||
("Now let’s **HACK!** 💻\n\n"
|
( "Now let’s **HACK** 💻... I want you to **HACK ME**!\n\n"
|
||||||
+ "I want you to **HACK ME**...\n\n"
|
+ "To **hack**, you need to run the `/hack` slash command.\n"
|
||||||
+ hackMessage
|
+ $"Type the `/hack` command now, then choose me - <@{Sensei.Id}> as your target, and select `{defaultHack.Name}`")
|
||||||
+ "To deploy it, you need to run the `/hack` slash command.\n"
|
} |> Async.StartAsTask :> Task
|
||||||
+ $"Type the `/hack` command now, then choose me - <@{GuildEnvironment.botIdHackerBattle}> as your target, and select `{weaponName}`")
|
|
||||||
})
|
|
||||||
|
|
||||||
let attack (target : DiscordUser) (ctx : IDiscordContext) =
|
let hack (target : DiscordUser) (ctx : IDiscordContext) =
|
||||||
Game.executePlayerAction ctx (fun player -> async {
|
Game.executePlayerAction ctx (fun player -> async {
|
||||||
let isRightTarget = target.Id = GuildEnvironment.botIdHackerBattle
|
let isRightTarget = target.Id = Sensei.Id
|
||||||
match isRightTarget with
|
match isRightTarget with
|
||||||
| true ->
|
| true ->
|
||||||
let playerWithAttacks =
|
let bot = { PlayerData.empty with DiscordId = Sensei.Id ; Name = Sensei.Name }
|
||||||
match Player.getHacks player with
|
let embed = Embeds.pickHack "Trainer-4" { player with Inventory = [| defaultHack |] } bot true
|
||||||
| [||] -> { player with Inventory = [| defaultHack |] }
|
|
||||||
| _ -> player
|
|
||||||
let bot = { player with DiscordId = GuildEnvironment.botIdHackerBattle ; Name = "Sensei" }
|
|
||||||
let embed = Embeds.pickHack "Trainer-4" playerWithAttacks bot true
|
|
||||||
|
|
||||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||||
| false ->
|
| false ->
|
||||||
@ -124,12 +117,11 @@ let attack (target : DiscordUser) (ctx : IDiscordContext) =
|
|||||||
do! ctx.FollowUp(builder) |> Async.AwaitTask
|
do! ctx.FollowUp(builder) |> Async.AwaitTask
|
||||||
})
|
})
|
||||||
|
|
||||||
let handleAttack (ctx : IDiscordContext) =
|
let handleHack (ctx : IDiscordContext) =
|
||||||
Game.executePlayerAction ctx (fun player -> async {
|
Game.executePlayerAction ctx (fun player -> async {
|
||||||
let sendMessage' = sendFollowUpMessage ctx
|
let sendMessage' = sendFollowUpMessage ctx
|
||||||
do! Async.Sleep 1000
|
do! Async.Sleep 1000
|
||||||
let hack = Player.getHacks player |> Array.tryHead |> Option.defaultValue defaultHack
|
let embed = Embeds.responseSuccessfulHack false Sensei.Id defaultHack
|
||||||
let embed = Embeds.responseSuccessfulHack false GuildEnvironment.botIdHackerBattle hack
|
|
||||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||||
do! Async.Sleep 5000
|
do! Async.Sleep 5000
|
||||||
do! sendMessage'
|
do! sendMessage'
|
||||||
@ -146,53 +138,14 @@ let handleAttack (ctx : IDiscordContext) =
|
|||||||
if isFirstTrainer then
|
if isFirstTrainer then
|
||||||
do! DbService.addAchievement player.DiscordId trainerAchievement
|
do! DbService.addAchievement player.DiscordId trainerAchievement
|
||||||
|
|
||||||
let hasHacks = Player.getHacks player |> Array.isEmpty |> not
|
sb.Append($"I'm going to gift you a hack,`{defaultHack.Name}` and a shield, `{defaultShield.Name}`") |> ignore
|
||||||
let hasShields = Player.getShields player |> Array.isEmpty |> not
|
|
||||||
|
|
||||||
let rand = System.Random(System.Guid.NewGuid().GetHashCode())
|
|
||||||
let freeHack = Armory.hacks.[rand.Next(0, 3)]
|
|
||||||
let freeShield = Armory.shields.[rand.Next(0, 3)]
|
|
||||||
let hackMoney = if hasHacks then defaultHack.Price else 0<GBT>
|
|
||||||
let shieldMoney = if hasShields then defaultShield.Price else 0<GBT>
|
|
||||||
|
|
||||||
let giftMsg =
|
|
||||||
match hasHacks , hasShields with
|
|
||||||
| true , true -> $"I'm going to give you these {hackMoney + shieldMoney} 💰$GBT"
|
|
||||||
| false , true -> $"I'm going to gift you a hack, `{freeHack.Name}` and {defaultHack.Price} 💰$GBT"
|
|
||||||
| true , false -> $"I'm going to gift you a shield, `{freeShield.Name}` and {defaultHack.Price} 💰$GBT"
|
|
||||||
| false , false -> $"I'm going to gift you a hack,`{freeHack.Name}` and a shield, `{freeShield.Name}`"
|
|
||||||
|
|
||||||
sb.Append(giftMsg) |> ignore
|
|
||||||
sb.Append(", you'll need em to survive\n\n") |> ignore
|
sb.Append(", you'll need em to survive\n\n") |> ignore
|
||||||
sb.AppendLine("To finish your training and collect the loot, type the `/arsenal` command **NOW**") |> ignore
|
sb.AppendLine("To finish your training and collect the loot, type the `/arsenal` command **NOW**") |> ignore
|
||||||
do! Async.Sleep 1000
|
do! Async.Sleep 1000
|
||||||
let updatedPlayer = {
|
|
||||||
player with
|
|
||||||
Bank = player.Bank + 100<GBT>
|
|
||||||
Events = [
|
|
||||||
{ PlayerEvent.Timestamp = System.DateTime.UtcNow
|
|
||||||
PlayerEvent.Adversary = { Id = GuildEnvironment.botIdHackerBattle ; Name = "Sensei" }
|
|
||||||
PlayerEvent.Type = PlayerEventType.Shielding
|
|
||||||
PlayerEvent.Result = PlayerEventResult.Positive
|
|
||||||
PlayerEvent.ItemId = defaultHack.Id }
|
|
||||||
if not hasShields && Array.exists (fun act -> act.ItemId = freeShield.Id) player.Events |> not then {
|
|
||||||
PlayerEvent.Timestamp = System.DateTime.UtcNow
|
|
||||||
PlayerEvent.Adversary = { Id = GuildEnvironment.botIdHackerBattle ; Name = "Sensei" }
|
|
||||||
PlayerEvent.Type = PlayerEventType.Shielding
|
|
||||||
PlayerEvent.Result = PlayerEventResult.Positive
|
|
||||||
PlayerEvent.ItemId = defaultHack.Id }
|
|
||||||
] |> Seq.toArray
|
|
||||||
|> Array.append player.Events
|
|
||||||
Inventory = [
|
|
||||||
if not hasHacks then freeHack
|
|
||||||
if not hasShields then freeShield
|
|
||||||
] |> Seq.toArray
|
|
||||||
|> Array.append player.Inventory
|
|
||||||
}
|
|
||||||
do! DbService.updatePlayer updatedPlayer
|
|
||||||
do! sendFollowUpMessage ctx (sb.ToString())
|
do! sendFollowUpMessage ctx (sb.ToString())
|
||||||
else
|
else
|
||||||
do! sendFollowUpMessage ctx ($"Your training is now complete. If you want to buy more **HACKS & SHIELDS**, go to the <#{GuildEnvironment.channelArmory}> **NOW** and type the `/buy-hack` and `/buy-shield` commands! 😱")
|
do! sendFollowUpMessage ctx ($"Your training is now complete. If you want to buy more **HACKS & SHIELDS**, go to the <#{GuildEnvironment.channelArmory}> and type the `/buy-hack` and `/buy-shield` commands!")
|
||||||
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee)
|
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee)
|
||||||
do! ctx.GetDiscordMember().RevokeRoleAsync(role)
|
do! ctx.GetDiscordMember().RevokeRoleAsync(role)
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
@ -200,9 +153,25 @@ let handleAttack (ctx : IDiscordContext) =
|
|||||||
|
|
||||||
let handleArsenal (ctx : IDiscordContext) =
|
let handleArsenal (ctx : IDiscordContext) =
|
||||||
Game.executePlayerAction ctx (fun player -> async {
|
Game.executePlayerAction ctx (fun player -> async {
|
||||||
|
let hasStockWeapons = Player.getHacks player |> Array.exists (fun item -> item.Id = defaultHack.Id)
|
||||||
let updatedPlayer = Player.removeExpiredActions false player
|
let updatedPlayer = Player.removeExpiredActions false player
|
||||||
let embed = Embeds.getArsenalEmbed updatedPlayer
|
let newPlayer =
|
||||||
|
if not hasStockWeapons then {
|
||||||
|
updatedPlayer with
|
||||||
|
Events = if not (player.Events |> Array.exists (fun act -> act.Adversary = Sensei))
|
||||||
|
then TrainerEvents
|
||||||
|
else [||]
|
||||||
|
|> Array.append player.Events
|
||||||
|
Inventory = if not hasStockWeapons then [| defaultHack ; defaultShield |] else Array.empty
|
||||||
|
|> Array.append player.Inventory
|
||||||
|
}
|
||||||
|
else
|
||||||
|
updatedPlayer
|
||||||
|
if not hasStockWeapons then
|
||||||
|
do! DbService.updatePlayer newPlayer
|
||||||
|
let embed = Embeds.getArsenalEmbed newPlayer
|
||||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||||
|
if not (player.Achievements |> Array.contains trainerAchievement) then
|
||||||
do! Async.Sleep 3000
|
do! Async.Sleep 3000
|
||||||
let embed = Embeds.getAchievementEmbed "You completed the Training Dojo and collected loot." trainerAchievement
|
let embed = Embeds.getAchievementEmbed "You completed the Training Dojo and collected loot." trainerAchievement
|
||||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||||
@ -220,7 +189,7 @@ let handleButtonEvent (ctx : IDiscordContext) =
|
|||||||
| 1 -> do! handleTrainerStep1 ctx |> Async.AwaitTask
|
| 1 -> do! handleTrainerStep1 ctx |> Async.AwaitTask
|
||||||
| 2 -> do! handleDefense ctx |> Async.AwaitTask
|
| 2 -> do! handleDefense ctx |> Async.AwaitTask
|
||||||
| 3 -> do! handleTrainerStep3 ctx |> Async.AwaitTask
|
| 3 -> do! handleTrainerStep3 ctx |> Async.AwaitTask
|
||||||
| 4 -> do! handleAttack ctx |> Async.AwaitTask
|
| 4 -> do! handleHack ctx |> Async.AwaitTask
|
||||||
| _ -> do! sendFollowUpMessage ctx "No action found"
|
| _ -> do! sendFollowUpMessage ctx "No action found"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +69,6 @@ let updatePlayer (player : PlayerData) =
|
|||||||
let addAchievement (id : uint64) (achievement : string) =
|
let addAchievement (id : uint64) (achievement : string) =
|
||||||
async {
|
async {
|
||||||
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", id)
|
let filter = Builders<BsonDocument>.Filter.Eq("Player.DiscordId", id)
|
||||||
let update = Builders<BsonDocument>.Update.Push("Achievements", achievement)
|
let update = Builders<BsonDocument>.Update.Push("Player.Achievements", achievement)
|
||||||
return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
|
return! players.UpdateOneAsync(filter, update) |> Async.AwaitTask |> Async.Ignore
|
||||||
}
|
}
|
@ -49,9 +49,17 @@ module Types =
|
|||||||
type ItemType =
|
type ItemType =
|
||||||
| Hack = 0
|
| Hack = 0
|
||||||
| Shield = 1
|
| Shield = 1
|
||||||
| Consumable = 1
|
| Food = 1
|
||||||
|
|
||||||
|
type ItemAttributes = {
|
||||||
|
Sell : bool
|
||||||
|
Buy : bool
|
||||||
|
Consume : bool
|
||||||
|
Drop : bool
|
||||||
|
}
|
||||||
|
with static member empty = { Sell = false ; Buy = false ; Consume = false ; Drop = false }
|
||||||
|
|
||||||
|
|
||||||
[<CLIMutable>]
|
|
||||||
type Item = {
|
type Item = {
|
||||||
Id : int
|
Id : int
|
||||||
Name : string
|
Name : string
|
||||||
@ -59,6 +67,7 @@ module Types =
|
|||||||
Type : ItemType
|
Type : ItemType
|
||||||
Power : int
|
Power : int
|
||||||
Cooldown : int<mins>
|
Cooldown : int<mins>
|
||||||
|
Attributes : ItemAttributes
|
||||||
}
|
}
|
||||||
|
|
||||||
type HackResult =
|
type HackResult =
|
||||||
@ -109,6 +118,15 @@ module Types =
|
|||||||
Bank : int<GBT>
|
Bank : int<GBT>
|
||||||
}
|
}
|
||||||
with member this.basicPlayer = { Id = this.DiscordId ; Name = this.Name }
|
with member this.basicPlayer = { Id = this.DiscordId ; Name = this.Name }
|
||||||
|
static member empty =
|
||||||
|
{ DiscordId = 0uL
|
||||||
|
Name = "None"
|
||||||
|
Inventory = [||]
|
||||||
|
Events = [||]
|
||||||
|
Traits = PlayerTraits.empty
|
||||||
|
Achievements = [||]
|
||||||
|
XP = 0
|
||||||
|
Bank = 0<GBT> }
|
||||||
|
|
||||||
module Armory =
|
module Armory =
|
||||||
let battleItems =
|
let battleItems =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user