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)))
|
||||
|> ignore
|
||||
embed
|
||||
.AddField("Cost 💰", $"{item.Price} $GBT", true)
|
||||
.AddField("Price 💰", $"{item.Price} $GBT", true)
|
||||
.WithTitle($"{item.Name}")
|
||||
|> ignore
|
||||
let button =
|
||||
|
32
Bot/Game.fs
32
Bot/Game.fs
@ -68,10 +68,10 @@ module Player =
|
||||
let getShields (player : PlayerData) = getItems ItemType.Shield player
|
||||
let getHackEvents player =
|
||||
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 =
|
||||
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
|
||||
// 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) =
|
||||
match actions with
|
||||
| [||] -> "None"
|
||||
| _ ->
|
||||
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
|
||||
| _ -> actions
|
||||
|> Array.map (fun act ->
|
||||
let item = Armory.getItem act.ItemId
|
||||
match act.Type with
|
||||
| PlayerEventType.Hacking ->
|
||||
let cooldown = Messaging.getTimeText false Game.SameTargetAttackCooldown act.Timestamp
|
||||
$"Hacked {act.Adversary.Name} {cooldown} ago"
|
||||
| _ ->
|
||||
let cooldown = Messaging.getTimeText true (System.TimeSpan.FromMinutes(int item.Cooldown)) act.Timestamp
|
||||
$"{item.Name} Shield active for {cooldown}")
|
||||
let item = Armory.getItem act.ItemId
|
||||
match act.Type with
|
||||
| PlayerEventType.Hacking ->
|
||||
let cooldown = Messaging.getTimeText false Game.SameTargetAttackCooldown act.Timestamp
|
||||
$"Hacked {act.Adversary.Name} with {item.Name} {cooldown} ago"
|
||||
| _ ->
|
||||
let cooldown = Messaging.getTimeText true (System.TimeSpan.FromMinutes(int item.Cooldown)) act.Timestamp
|
||||
$"{item.Name} Shield active for {cooldown}")
|
||||
|> String.concat "\n"
|
||||
|
||||
let statusFormat p =
|
||||
let hacks = Player.getHackEvents p
|
||||
$"**Hacks:** {Player.getHacks 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}"
|
||||
|
||||
|
@ -264,7 +264,7 @@ type HackerGame() =
|
||||
|
||||
[<SlashCommand("hack", "Send a hack attack to another player")>]
|
||||
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")>]
|
||||
member this.ShieldCommand (ctx : InteractionContext) =
|
||||
|
@ -3,48 +3,84 @@
|
||||
"Id": 0,
|
||||
"Name": "Virus",
|
||||
"Type": 0,
|
||||
"Cost": 50,
|
||||
"Power": 50,
|
||||
"Cooldown": 2
|
||||
"Price": 0,
|
||||
"Power": 10,
|
||||
"Cooldown": 2,
|
||||
"Attributes": {
|
||||
"Sell": false,
|
||||
"Buy": false,
|
||||
"Consume": false,
|
||||
"Drop": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": 1,
|
||||
"Name": "RemoteAccess",
|
||||
"Type": 0,
|
||||
"Cost": 50,
|
||||
"Price": 500,
|
||||
"Power": 50,
|
||||
"Cooldown": 2
|
||||
"Cooldown": 2,
|
||||
"Attributes": {
|
||||
"Sell": true,
|
||||
"Buy": true,
|
||||
"Consume": false,
|
||||
"Drop": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"Name": "Worm",
|
||||
"Type": 0,
|
||||
"Cost": 50,
|
||||
"Power": 50,
|
||||
"Cooldown": 2
|
||||
"Price": 5000,
|
||||
"Power": 80,
|
||||
"Cooldown": 2,
|
||||
"Attributes": {
|
||||
"Sell": true,
|
||||
"Buy": true,
|
||||
"Consume": false,
|
||||
"Drop": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": 6,
|
||||
"Name": "Firewall",
|
||||
"Type": 1,
|
||||
"Cost": 50,
|
||||
"Power": 50,
|
||||
"Cooldown": 600
|
||||
"Price": 0,
|
||||
"Power": 10,
|
||||
"Cooldown": 600,
|
||||
"Attributes": {
|
||||
"Sell": false,
|
||||
"Buy": false,
|
||||
"Consume": false,
|
||||
"Drop": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": 8,
|
||||
"Name": "Cypher",
|
||||
"Type": 1,
|
||||
"Cost": 50,
|
||||
"Price": 500,
|
||||
"Power": 50,
|
||||
"Cooldown": 600
|
||||
"Cooldown": 600,
|
||||
"Attributes": {
|
||||
"Sell": true,
|
||||
"Buy": true,
|
||||
"Consume": false,
|
||||
"Drop": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"Id": 7,
|
||||
"Name": "Encryption",
|
||||
"Type": 1,
|
||||
"Cost": 50,
|
||||
"Power": 50,
|
||||
"Cooldown": 600
|
||||
"Price": 5000,
|
||||
"Power": 80,
|
||||
"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 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 }
|
||||
let newLevel = XP.getLevel (player.XP + xp)
|
||||
// if XP.getLevel player.XP < newLevel then
|
||||
do! Async.Sleep 2000
|
||||
do! ctx.FollowUp (XP.getRewardsEmbed 1 player) |> Async.AwaitTask
|
||||
| false , false ->
|
||||
|
171
Bot/Trainer.fs
171
Bot/Trainer.fs
@ -1,16 +1,29 @@
|
||||
module Degenz.Trainer
|
||||
|
||||
open System.Text
|
||||
open System.Threading.Tasks
|
||||
open DSharpPlus
|
||||
open DSharpPlus.Entities
|
||||
open DSharpPlus.EventArgs
|
||||
open Degenz.Types
|
||||
open Degenz.Messaging
|
||||
|
||||
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 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) =
|
||||
async {
|
||||
@ -31,42 +44,31 @@ let sendInitialEmbed (client : DiscordClient) =
|
||||
|
||||
let handleTrainerStep1 (ctx : IDiscordContext) =
|
||||
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)
|
||||
do! ctx.GetDiscordMember().GrantRoleAsync(role)
|
||||
|> Async.AwaitTask
|
||||
|
||||
do! sendFollowUpMessage ctx
|
||||
("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"
|
||||
+ $"Type the `/shield` command now, then select - `{weaponName}`\n")
|
||||
+ $"Type the `/shield` command now, then select - `{defaultShield.Name}`\n")
|
||||
})
|
||||
|
||||
let defend (ctx : IDiscordContext) =
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
let playerWithShields =
|
||||
match Player.getShields player with
|
||||
| [||] -> { player with Inventory = [| defaultShield |] }
|
||||
| _ -> player
|
||||
|
||||
let embed = Embeds.pickDefense "Trainer-2" playerWithShields true
|
||||
|
||||
async {
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.IsEphemeral <- true
|
||||
builder.Content <- "Content"
|
||||
do! ctx.Respond InteractionResponseType.DeferredChannelMessageWithSource builder |> Async.AwaitTask
|
||||
let embed = Embeds.pickDefense "Trainer-2" { PlayerData.empty with Inventory = [| defaultShield |] } true
|
||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||
})
|
||||
} |> Async.StartAsTask :> Task
|
||||
|
||||
let handleDefenseMsg shieldId hackId = {
|
||||
let handleDefenseMsg hackId = {
|
||||
ButtonId = "Trainer-3"
|
||||
ButtonText = "Got it"
|
||||
Message = "🎉 Congratulations you successfully defended my 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!"
|
||||
Message = $"🎉 Congratulations you successfully defended my {hackId} hack!\n\n"
|
||||
+ "Shields only protect you for a LIMITED TIME, so remember to keep them mounted at all times, or risk getting hacked!"
|
||||
}
|
||||
|
||||
let handleDefense (ctx : IDiscordContext) =
|
||||
@ -78,41 +80,32 @@ let handleDefense (ctx : IDiscordContext) =
|
||||
let embed = Embeds.responseCreatedShield shield
|
||||
do! ctx.FollowUp embed |> Async.AwaitTask
|
||||
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! 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! sendFollowUpMessageWithButton ctx (handleDefenseMsg shieldId "VIRUS")
|
||||
|
||||
do! sendFollowUpMessageWithButton ctx (handleDefenseMsg defaultHack.Name)
|
||||
})
|
||||
|
||||
let handleTrainerStep3 (ctx : IDiscordContext) =
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
let hackMessage , weaponName =
|
||||
if Player.getHacks player |> Array.isEmpty
|
||||
then $"You do not have any Hacks in your arsenal, take this `{defaultHack.Name}`, you can use it for now.\n\n" , defaultHack.Name
|
||||
else
|
||||
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
|
||||
|
||||
async {
|
||||
let builder = DiscordInteractionResponseBuilder()
|
||||
builder.IsEphemeral <- true
|
||||
builder.Content <- "Content"
|
||||
do! ctx.Respond InteractionResponseType.DeferredChannelMessageWithSource builder |> Async.AwaitTask
|
||||
do! sendFollowUpMessage ctx
|
||||
("Now let’s **HACK!** 💻\n\n"
|
||||
+ "I want you to **HACK ME**...\n\n"
|
||||
+ hackMessage
|
||||
+ "To deploy it, you need to run the `/hack` slash command.\n"
|
||||
+ $"Type the `/hack` command now, then choose me - <@{GuildEnvironment.botIdHackerBattle}> as your target, and select `{weaponName}`")
|
||||
})
|
||||
( "Now let’s **HACK** 💻... I want you to **HACK ME**!\n\n"
|
||||
+ "To **hack**, you need to run the `/hack` slash command.\n"
|
||||
+ $"Type the `/hack` command now, then choose me - <@{Sensei.Id}> as your target, and select `{defaultHack.Name}`")
|
||||
} |> Async.StartAsTask :> Task
|
||||
|
||||
let attack (target : DiscordUser) (ctx : IDiscordContext) =
|
||||
let hack (target : DiscordUser) (ctx : IDiscordContext) =
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
let isRightTarget = target.Id = GuildEnvironment.botIdHackerBattle
|
||||
let isRightTarget = target.Id = Sensei.Id
|
||||
match isRightTarget with
|
||||
| true ->
|
||||
let playerWithAttacks =
|
||||
match Player.getHacks player with
|
||||
| [||] -> { player with Inventory = [| defaultHack |] }
|
||||
| _ -> player
|
||||
let bot = { player with DiscordId = GuildEnvironment.botIdHackerBattle ; Name = "Sensei" }
|
||||
let embed = Embeds.pickHack "Trainer-4" playerWithAttacks bot true
|
||||
let bot = { PlayerData.empty with DiscordId = Sensei.Id ; Name = Sensei.Name }
|
||||
let embed = Embeds.pickHack "Trainer-4" { player with Inventory = [| defaultHack |] } bot true
|
||||
|
||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||
| false ->
|
||||
@ -124,12 +117,11 @@ let attack (target : DiscordUser) (ctx : IDiscordContext) =
|
||||
do! ctx.FollowUp(builder) |> Async.AwaitTask
|
||||
})
|
||||
|
||||
let handleAttack (ctx : IDiscordContext) =
|
||||
let handleHack (ctx : IDiscordContext) =
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
let sendMessage' = sendFollowUpMessage ctx
|
||||
do! Async.Sleep 1000
|
||||
let hack = Player.getHacks player |> Array.tryHead |> Option.defaultValue defaultHack
|
||||
let embed = Embeds.responseSuccessfulHack false GuildEnvironment.botIdHackerBattle hack
|
||||
let embed = Embeds.responseSuccessfulHack false Sensei.Id defaultHack
|
||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||
do! Async.Sleep 5000
|
||||
do! sendMessage'
|
||||
@ -146,53 +138,14 @@ let handleAttack (ctx : IDiscordContext) =
|
||||
if isFirstTrainer then
|
||||
do! DbService.addAchievement player.DiscordId trainerAchievement
|
||||
|
||||
let hasHacks = Player.getHacks player |> Array.isEmpty |> not
|
||||
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($"I'm going to gift you a hack,`{defaultHack.Name}` and a shield, `{defaultShield.Name}`") |> 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
|
||||
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())
|
||||
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)
|
||||
do! ctx.GetDiscordMember().RevokeRoleAsync(role)
|
||||
|> Async.AwaitTask
|
||||
@ -200,12 +153,28 @@ let handleAttack (ctx : IDiscordContext) =
|
||||
|
||||
let handleArsenal (ctx : IDiscordContext) =
|
||||
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 embed = Embeds.getArsenalEmbed updatedPlayer
|
||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||
do! Async.Sleep 3000
|
||||
let embed = Embeds.getAchievementEmbed "You completed the Training Dojo and collected loot." trainerAchievement
|
||||
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
|
||||
if not (player.Achievements |> Array.contains trainerAchievement) then
|
||||
do! Async.Sleep 3000
|
||||
let embed = Embeds.getAchievementEmbed "You completed the Training Dojo and collected loot." trainerAchievement
|
||||
do! ctx.FollowUp(embed) |> Async.AwaitTask
|
||||
do! Async.Sleep 2000
|
||||
let role = ctx.GetGuild().GetRole(GuildEnvironment.roleTrainee)
|
||||
do! ctx.GetDiscordMember().RevokeRoleAsync(role) |> Async.AwaitTask
|
||||
@ -220,7 +189,7 @@ let handleButtonEvent (ctx : IDiscordContext) =
|
||||
| 1 -> do! handleTrainerStep1 ctx |> Async.AwaitTask
|
||||
| 2 -> do! handleDefense 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"
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,6 @@ let updatePlayer (player : PlayerData) =
|
||||
let addAchievement (id : uint64) (achievement : string) =
|
||||
async {
|
||||
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
|
||||
}
|
@ -49,9 +49,17 @@ module Types =
|
||||
type ItemType =
|
||||
| Hack = 0
|
||||
| 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 = {
|
||||
Id : int
|
||||
Name : string
|
||||
@ -59,6 +67,7 @@ module Types =
|
||||
Type : ItemType
|
||||
Power : int
|
||||
Cooldown : int<mins>
|
||||
Attributes : ItemAttributes
|
||||
}
|
||||
|
||||
type HackResult =
|
||||
@ -109,6 +118,15 @@ module Types =
|
||||
Bank : int<GBT>
|
||||
}
|
||||
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 =
|
||||
let battleItems =
|
||||
|
Loading…
x
Reference in New Issue
Block a user