Steal embed improvements, bug fixes, more fields for Events
This commit is contained in:
parent
63e3853788
commit
f7391682fd
@ -44,7 +44,7 @@ let storeCommands = storeBot.UseSlashCommands()
|
||||
|
||||
hackerCommands.RegisterCommands<HackerGame>(guild);
|
||||
hackerCommands.RegisterCommands<StealGame>(guild);
|
||||
hackerCommands.RegisterCommands<RPSGame>(guild);
|
||||
//hackerCommands.RegisterCommands<RPSGame>(guild);
|
||||
storeCommands.RegisterCommands<Store>(guild);
|
||||
//sc3.RegisterCommands<SlotMachine>(guild);
|
||||
|
||||
|
@ -165,7 +165,7 @@ let getArsenalEmbed (player : PlayerData) =
|
||||
DiscordEmbedBuilder()
|
||||
.AddField( "Arsenal", Arsenal.statusFormat player ))
|
||||
|
||||
let getAchievementEmbed description achievement =
|
||||
let getAchievementEmbed rewards description achievement =
|
||||
let embed = DiscordEmbedBuilder()
|
||||
|
||||
GuildEnvironment.botUserHackerBattle
|
||||
@ -176,12 +176,12 @@ let getAchievementEmbed description achievement =
|
||||
|
||||
DiscordFollowupMessageBuilder()
|
||||
.AddEmbed(
|
||||
// TODO: We can add a Reward field but we'd need to keep track of what the player was awarded
|
||||
embed.WithTitle("Achievement Unlocked!")
|
||||
.WithDescription(description)
|
||||
.WithColor(DiscordColor.Gold)
|
||||
// .AddField("Achievement", $"🏆 {achievement}")
|
||||
.AddField("Achievement", $"{achievement}")
|
||||
.AddField("Achievement", $"{achievement}", true)
|
||||
.AddField("Rewards", rewards |> String.concat "\n", true)
|
||||
// TODO: Once we add another achievement, fix this
|
||||
.WithImageUrl("https://s10.gifyu.com/images/MasterTraining_Degenz.gif"))
|
||||
.AsEphemeral(true)
|
20
Bot/Game.fs
20
Bot/Game.fs
@ -73,26 +73,12 @@ module Player =
|
||||
player.Events
|
||||
|> 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
|
||||
let removeExpiredActions filterByAttackCooldown player =
|
||||
let removeExpiredActions player =
|
||||
let actions =
|
||||
player.Events
|
||||
|> Array.filter (fun (act : PlayerEvent) ->
|
||||
let itemCooldown =
|
||||
if act.ItemId > 0 && act.ItemId < 12 then
|
||||
(Armory.getItem act.ItemId).Cooldown
|
||||
else
|
||||
match act.Type with
|
||||
| PlayerEventType.Steal -> 1<mins>
|
||||
| _ -> 720<mins>
|
||||
|> int
|
||||
|
||||
match act.Type , filterByAttackCooldown with
|
||||
| PlayerEventType.Hacking , true -> System.DateTime.UtcNow - act.Timestamp < System.TimeSpan.FromMinutes(itemCooldown)
|
||||
| PlayerEventType.Hacking , false -> System.DateTime.UtcNow - act.Timestamp < Game.SameTargetAttackCooldown
|
||||
| PlayerEventType.Shielding , _ -> System.DateTime.UtcNow - act.Timestamp < System.TimeSpan.FromMinutes(itemCooldown)
|
||||
| _ -> System.DateTime.UtcNow - act.Timestamp < System.TimeSpan.FromMinutes(itemCooldown))
|
||||
let cooldown = System.TimeSpan.FromMinutes(int act.Cooldown)
|
||||
System.DateTime.UtcNow - act.Timestamp < cooldown)
|
||||
{ player with Events = actions }
|
||||
|
||||
let modifyBank (player : PlayerData) amount = { player with Bank = max (player.Bank + amount) 0<GBT> }
|
||||
|
@ -14,37 +14,30 @@ let checkPlayerIsAttackingThemselves defender attacker =
|
||||
| true -> Error "You think you're clever? You can't hack yourself, pal."
|
||||
| false -> Ok attacker
|
||||
|
||||
let checkAlreadyHackedTarget defenderId attacker =
|
||||
attacker.Events
|
||||
|> Array.tryFind (fun pe -> pe.Adversary.Id = defenderId)
|
||||
let checkAlreadyHackedTarget defender attacker =
|
||||
defender.Events
|
||||
|> Array.tryFind (fun event -> event.Adversary.Id = attacker.DiscordId && event.IsInstigator = false)
|
||||
|> function
|
||||
| Some event ->
|
||||
let cooldown = getTimeText true Game.SameTargetAttackCooldown event.Timestamp
|
||||
Error $"You can only hack the same target once every {Game.SameTargetAttackCooldown.Hours} hours, wait {cooldown} to attempt another hack on {event.Adversary.Name}."
|
||||
Error $"You can only hack the same target once every {Game.SameTargetAttackCooldown.Hours} hours, wait {cooldown} to attempt another hack on <@{defender.DiscordId}>."
|
||||
| None -> Ok attacker
|
||||
|
||||
let checkItemHasCooldown itemId attacker =
|
||||
let cooldown =
|
||||
attacker.Events
|
||||
|> Array.tryFind (fun a -> a.ItemId = itemId)
|
||||
|> function
|
||||
| Some a -> a.Timestamp
|
||||
| None -> DateTime.MinValue
|
||||
let item = Armory.getItem itemId
|
||||
if DateTime.UtcNow - cooldown > TimeSpan.FromMinutes(int item.Cooldown) then
|
||||
Ok attacker
|
||||
else
|
||||
let cooldown = getTimeText true (TimeSpan.FromMinutes(int item.Cooldown)) cooldown
|
||||
let item = Armory.battleItems |> Array.find (fun i -> i.Id = itemId)
|
||||
Error $"{item.Name} is currently on cooldown, wait {cooldown} to use it again."
|
||||
let checkWeaponHasCooldown (weapon : Item) attacker =
|
||||
let cooldown = attacker.Events |> Array.tryFind (fun a -> a.ItemId = weapon.Id)
|
||||
match cooldown with
|
||||
| Some event ->
|
||||
let cooldown = getTimeText true (TimeSpan.FromMinutes(int event.Cooldown)) event.Timestamp
|
||||
Error $"{weapon.Name} is still active, it will expire in {cooldown}."
|
||||
| None -> Ok attacker
|
||||
|
||||
let checkHasEmptyHacks attacker =
|
||||
match Player.getHacks attacker with
|
||||
| [||] -> Error $"You currently do not have any Hacks to steal 💰$GBT from others. Please go to the <#{GuildEnvironment.channelArmory}> and purchase one."
|
||||
| _ -> Ok attacker
|
||||
|
||||
let checkPlayerOwnsWeapon itemId player =
|
||||
match player.Inventory |> Array.exists (fun i -> i.Id = itemId) with
|
||||
let checkPlayerOwnsWeapon (item : Item) player =
|
||||
match player.Inventory |> Array.exists (fun i -> i.Id = item.Id) with
|
||||
| true -> Ok player
|
||||
| false -> Error $"You sold your weapon already, you cheeky bastard..."
|
||||
|
||||
@ -53,8 +46,8 @@ let checkTargetHasMoney (target : PlayerData) attacker =
|
||||
then Error $"{target.Name} does not have enough 💰$GBT to steal from, the broke loser. Pick a different target."
|
||||
else Ok attacker
|
||||
|
||||
let checkPlayerHasShieldSlotsAvailable shield player =
|
||||
let updatedPlayer = player |> Player.removeExpiredActions false
|
||||
let checkPlayerHasShieldSlotsAvailable (shield : Item) player =
|
||||
let updatedPlayer = player |> Player.removeExpiredActions
|
||||
let defenses = Player.getShieldEvents updatedPlayer
|
||||
match defenses |> Array.length >= 2 with
|
||||
| true ->
|
||||
@ -71,37 +64,40 @@ let calculateDamage (hack : Item) (shield : Item) =
|
||||
|
||||
let runHackerBattle defender hack =
|
||||
defender
|
||||
|> Player.removeExpiredActions false
|
||||
|> Player.removeExpiredActions
|
||||
|> Player.getShieldEvents
|
||||
|> Array.map (fun dfn -> Armory.battleItems |> Array.find (fun w -> w.Id = dfn.ItemId))
|
||||
|> Array.map (calculateDamage (hack))
|
||||
|> Array.contains Weak
|
||||
|
||||
let updateCombatants attacker defender hack prize =
|
||||
let updateCombatants successfulHack (attacker : PlayerData) (defender : PlayerData) (hack : Item) prize =
|
||||
let updatePlayer amount attack p =
|
||||
{ p with Events = Array.append [| attack |] p.Events ; Bank = max (p.Bank + amount) 0<GBT> }
|
||||
let target = { Id = defender.DiscordId ; Name = defender.Name }
|
||||
let attack = {
|
||||
ItemId = int hack
|
||||
let event isDefenderEvent = {
|
||||
ItemId = hack.Id
|
||||
Type = PlayerEventType.Hacking
|
||||
Adversary = target
|
||||
Result = if prize > 0<GBT> then PlayerEventResult.Positive else PlayerEventResult.Negative
|
||||
Adversary = if isDefenderEvent then attacker.basicPlayer else defender.basicPlayer
|
||||
Cooldown = if isDefenderEvent then Game.SameTargetAttackCooldown.Minutes * 1<mins> else hack.Cooldown
|
||||
Timestamp = DateTime.UtcNow
|
||||
IsInstigator = not isDefenderEvent
|
||||
Result =
|
||||
match successfulHack , isDefenderEvent with
|
||||
| true , true -> PlayerEventResult.Negative
|
||||
| false , true -> PlayerEventResult.Positive
|
||||
| true , false -> PlayerEventResult.Positive
|
||||
| false , false -> PlayerEventResult.Negative
|
||||
}
|
||||
|
||||
// TODO: This is what I was talking about, this isn't a "Shield" event, this is a hack event but there's an adversary
|
||||
// who loses, so the event itself is to just "hack", so there's no "mugged" event, there's just a failed steal defense
|
||||
// or something like that.
|
||||
[ DbService.updatePlayer <| updatePlayer prize attack attacker
|
||||
DbService.updatePlayer <| Player.modifyBank defender -prize ]
|
||||
[ DbService.updatePlayer <| updatePlayer prize (event false) attacker
|
||||
DbService.updatePlayer <| updatePlayer -prize (event true) defender ]
|
||||
|> Async.Parallel
|
||||
|> Async.Ignore
|
||||
|
||||
let successfulHack (ctx : IDiscordContext) attacker defender hack =
|
||||
async {
|
||||
do! updateCombatants attacker defender hack Game.HackPrize
|
||||
do! updateCombatants true attacker defender hack Game.HackPrize
|
||||
|
||||
let embed = Embeds.responseSuccessfulHack true defender.DiscordId (Armory.getItem hack)
|
||||
let embed = Embeds.responseSuccessfulHack true defender.DiscordId hack
|
||||
do! ctx.FollowUp embed |> Async.AwaitTask
|
||||
|
||||
let builder = Embeds.eventSuccessfulHack ctx defender Game.HackPrize
|
||||
@ -116,7 +112,7 @@ let failedHack (ctx : IDiscordContext) attacker defender hack =
|
||||
let msg = $"Hack failed! {defender.Name} was able to mount a successful defense! You lost {Game.ShieldPrize} $GBT!"
|
||||
do! sendFollowUpMessage ctx msg
|
||||
|
||||
do! updateCombatants attacker defender hack -Game.ShieldPrize
|
||||
do! updateCombatants false attacker defender hack -Game.ShieldPrize
|
||||
|
||||
let builder = DiscordMessageBuilder()
|
||||
builder.WithContent($"Hacking attempt failed! <@{defender.DiscordId}> defended hack from {ctx.GetDiscordMember().Username} and stole {Game.ShieldPrize} $GBT from them! ") |> ignore
|
||||
@ -129,8 +125,8 @@ let failedHack (ctx : IDiscordContext) attacker defender hack =
|
||||
let attack (target : DiscordUser) (ctx : IDiscordContext) =
|
||||
Game.executePlayerActionWithTarget target ctx (fun attacker defender -> async {
|
||||
do! attacker
|
||||
|> checkAlreadyHackedTarget defender.DiscordId
|
||||
<!> (Player.removeExpiredActions true)
|
||||
|> checkAlreadyHackedTarget defender
|
||||
<!> Player.removeExpiredActions
|
||||
>>= checkHasEmptyHacks
|
||||
>>= checkTargetHasMoney defender
|
||||
>>= checkPlayerIsAttackingThemselves defender
|
||||
@ -145,23 +141,23 @@ let handleAttack (ctx : IDiscordContext) =
|
||||
Game.executePlayerAction ctx (fun attacker -> async {
|
||||
let split = ctx.GetInteractionId().Split("-")
|
||||
let hackId = int split.[1]
|
||||
let hack = enum<HackId>(hackId)
|
||||
let ( resultId , targetId ) = UInt64.TryParse split.[2]
|
||||
let hack = Armory.getItem hackId
|
||||
let resultId , targetId = UInt64.TryParse split.[2]
|
||||
let! resultTarget = DbService.tryFindPlayer targetId
|
||||
|
||||
match resultTarget , true , resultId with
|
||||
| Some defender , true , true ->
|
||||
do! attacker
|
||||
|> Player.removeExpiredActions false
|
||||
|> checkAlreadyHackedTarget defender.DiscordId
|
||||
>>= checkPlayerOwnsWeapon hackId
|
||||
>>= checkItemHasCooldown hackId
|
||||
|> Player.removeExpiredActions
|
||||
|> checkAlreadyHackedTarget defender
|
||||
>>= checkPlayerOwnsWeapon hack
|
||||
>>= checkWeaponHasCooldown hack
|
||||
|> function
|
||||
| Ok atkr ->
|
||||
runHackerBattle defender (Armory.getItem (int hackId))
|
||||
runHackerBattle defender hack
|
||||
|> function
|
||||
| false -> successfulHack ctx atkr defender hackId
|
||||
| true -> failedHack ctx attacker defender hackId
|
||||
| false -> successfulHack ctx atkr defender hack
|
||||
| true -> failedHack ctx attacker defender hack
|
||||
| Error msg -> Messaging.sendFollowUpMessage ctx msg
|
||||
| _ -> do! Messaging.sendFollowUpMessage ctx "Error occurred processing attack"
|
||||
})
|
||||
@ -169,7 +165,7 @@ let handleAttack (ctx : IDiscordContext) =
|
||||
let defend (ctx : IDiscordContext) =
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
if Player.getShields player |> Array.length > 0 then
|
||||
let p = Player.removeExpiredActions false player
|
||||
let p = Player.removeExpiredActions player
|
||||
let embed = Embeds.pickDefense "Defend" p false
|
||||
do! ctx.FollowUp embed |> Async.AwaitTask
|
||||
else
|
||||
@ -184,20 +180,22 @@ let handleDefense (ctx : IDiscordContext) =
|
||||
let shield = Armory.getItem shieldId
|
||||
|
||||
do! player
|
||||
|> checkPlayerOwnsWeapon shieldId
|
||||
|> checkPlayerOwnsWeapon shield
|
||||
>>= checkPlayerHasShieldSlotsAvailable shield
|
||||
>>= checkItemHasCooldown shieldId
|
||||
|> handleResultWithResponse ctx (fun _ -> async { // Don't use this player, it removes player cooldowns
|
||||
let embed = Embeds.responseCreatedShield (Armory.getItem shieldId)
|
||||
>>= checkWeaponHasCooldown shield
|
||||
|> handleResultWithResponse ctx (fun p -> async {
|
||||
let embed = Embeds.responseCreatedShield shield
|
||||
do! ctx.FollowUp embed |> Async.AwaitTask
|
||||
let defense = {
|
||||
ItemId = shieldId
|
||||
Type = PlayerEventType.Shielding
|
||||
Result = PlayerEventResult.Positive
|
||||
Timestamp = DateTime.UtcNow
|
||||
Cooldown = shield.Cooldown
|
||||
IsInstigator = true
|
||||
Adversary = DiscordPlayer.empty
|
||||
}
|
||||
do! DbService.updatePlayer <| { player with Events = Array.append [| defense |] player.Events }
|
||||
do! DbService.updatePlayer <| { p with Events = Array.append [| defense |] p.Events }
|
||||
let builder = DiscordMessageBuilder()
|
||||
builder.WithContent($"{ctx.GetDiscordMember().Username} has protected their system!") |> ignore
|
||||
let channel = ctx.GetGuild().GetChannel(GuildEnvironment.channelEventsHackerBattle)
|
||||
@ -209,7 +207,7 @@ let handleDefense (ctx : IDiscordContext) =
|
||||
|
||||
let arsenal (ctx : IDiscordContext) =
|
||||
Game.executePlayerAction ctx (fun player -> async {
|
||||
let updatedPlayer = Player.removeExpiredActions false player
|
||||
let updatedPlayer = Player.removeExpiredActions player
|
||||
let builder = DiscordFollowupMessageBuilder()
|
||||
let embed = DiscordEmbedBuilder()
|
||||
embed.AddField("Arsenal", Arsenal.statusFormat updatedPlayer) |> ignore
|
||||
|
54
Bot/Thief.fs
54
Bot/Thief.fs
@ -92,8 +92,8 @@ let getResultEmbed chance prize (bank : int<GBT>) thief (victim : DiscordPlayer)
|
||||
|
||||
let checkVictimStealingCooldown defender attacker =
|
||||
defender
|
||||
|> Player.removeExpiredActions false
|
||||
|> Player.getShieldEvents
|
||||
|> Player.removeExpiredActions
|
||||
|> fun p -> p.Events
|
||||
|> Array.tryFind (fun pe -> pe.Type = PlayerEventType.Steal && pe.Result = PlayerEventResult.Negative)
|
||||
|> function
|
||||
| Some act ->
|
||||
@ -102,19 +102,16 @@ let checkVictimStealingCooldown defender attacker =
|
||||
Error $"{defender.Name} was robbed recently so they won't be going out for at least another {hours}."
|
||||
| None -> Ok attacker
|
||||
|
||||
// TODO: Look for ways to generalize checking for action cooldowns
|
||||
let checkThiefCooldown attacker =
|
||||
attacker
|
||||
|> Player.getHackEvents
|
||||
|> Player.removeExpiredActions
|
||||
|> fun p -> p.Events
|
||||
|> Array.tryFind (fun pe -> pe.Type = PlayerEventType.Steal)
|
||||
|> function
|
||||
| Some act ->
|
||||
if ThiefCooldown > (DateTime.UtcNow - act.Timestamp) then
|
||||
let cooldown = ThiefCooldown - (DateTime.UtcNow - act.Timestamp)
|
||||
let minutes = if cooldown.Minutes = 0 then "minute" else $"{cooldown.Minutes} minutes"
|
||||
Error $"Whoa there you clepto, wait at least another {minutes} before you try stealing again."
|
||||
else
|
||||
Ok attacker
|
||||
let cooldown = ThiefCooldown - (DateTime.UtcNow - act.Timestamp)
|
||||
let minutes = if cooldown.Minutes = 0 then "minute" else $"{cooldown.Minutes} minutes"
|
||||
Error $"Whoa there you clepto, wait at least another {minutes} before you try stealing again."
|
||||
| None -> Ok attacker
|
||||
|
||||
|
||||
@ -157,7 +154,15 @@ let handleSteal (ctx : IDiscordContext) =
|
||||
let num = rand.NextDouble()
|
||||
let result = winPercentage >= num , rand.Next(0,3) = 0
|
||||
let dp = { DiscordPlayer.Id = targetId ; DiscordPlayer.Name = targetName }
|
||||
let stealAction result = { ItemId = -1 ; Type = PlayerEventType.Steal ; Result = result ; Adversary = dp ; Timestamp = DateTime.UtcNow }
|
||||
let stealAction result = {
|
||||
ItemId = -1
|
||||
Type = PlayerEventType.Steal
|
||||
Result = result
|
||||
Adversary = dp
|
||||
IsInstigator = true
|
||||
Cooldown = ThiefCooldown.Minutes * 1<mins>
|
||||
Timestamp = DateTime.UtcNow
|
||||
}
|
||||
let getResultEmbed' = getResultEmbed winPercentage prize thief.Bank thief dp
|
||||
// TODO: Send event to the hall of privacy
|
||||
// TODO: We need to check if the player is on cooldown
|
||||
@ -169,12 +174,29 @@ let handleSteal (ctx : IDiscordContext) =
|
||||
do! Messaging.sendFollowUpEmbed ctx (embed.Build())
|
||||
match! DbService.tryFindPlayer targetId with
|
||||
| Some t ->
|
||||
let mugged = { ItemId = -1 ; Type = PlayerEventType.Steal ; Result = PlayerEventResult.Negative ; Adversary = thief.basicPlayer ; Timestamp = DateTime.UtcNow }
|
||||
let actions = t |> Player.removeExpiredActions false |> fun p -> Array.append [| mugged |] p.Events
|
||||
let mugged = {
|
||||
ItemId = -1
|
||||
Type = PlayerEventType.Steal
|
||||
Result = PlayerEventResult.Negative
|
||||
Adversary = thief.basicPlayer
|
||||
Timestamp = DateTime.UtcNow
|
||||
IsInstigator = false
|
||||
Cooldown = VictimRecovery.Minutes * 1<mins>
|
||||
}
|
||||
let actions = t |> Player.removeExpiredActions |> fun p -> Array.append [| mugged |] p.Events
|
||||
do! DbService.updatePlayer { t with Bank = max (t.Bank - prize) 0<GBT> ; Events = actions }
|
||||
| None -> ()
|
||||
let stole = { ItemId = -1 ; Type = PlayerEventType.Steal ; Result = PlayerEventResult.Positive ; Adversary = dp ; Timestamp = DateTime.UtcNow }
|
||||
let actions = thief |> Player.removeExpiredActions false |> fun p -> Array.append [| stole |] p.Events
|
||||
|
||||
let stole = {
|
||||
ItemId = -1
|
||||
Type = PlayerEventType.Steal
|
||||
Result = PlayerEventResult.Positive
|
||||
Adversary = dp
|
||||
Timestamp = DateTime.UtcNow
|
||||
IsInstigator = true
|
||||
Cooldown = ThiefCooldown.Minutes * 1<mins>
|
||||
}
|
||||
let actions = thief |> Player.removeExpiredActions |> fun p -> Array.append [| stole |] p.Events
|
||||
do! DbService.updatePlayer { thief with Bank = thief.Bank + prize ; XP = thief.XP + 0 ; Events = actions }
|
||||
// do! Async.Sleep 2000
|
||||
// do! ctx.FollowUp (XP.getRewardsEmbed 1 player) |> Async.AwaitTask
|
||||
@ -194,7 +216,7 @@ let handleSteal (ctx : IDiscordContext) =
|
||||
let targetId = uint64 split.[2]
|
||||
Game.executePlayerActionWithTargetId true targetId ctx (fun attacker defender -> async {
|
||||
do! attacker
|
||||
|> Player.removeExpiredActions false
|
||||
|> Player.removeExpiredActions
|
||||
|> checkVictimStealingCooldown defender
|
||||
>>= checkThiefCooldown
|
||||
|> handleResultWithResponse ctx (handleYes defender )
|
||||
|
@ -13,16 +13,20 @@ let defaultHack = Armory.battleItems |> Array.find (fun i -> i.Id = int HackId.V
|
||||
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 }
|
||||
{ Timestamp = System.DateTime.UtcNow
|
||||
Adversary = Sensei
|
||||
Type = PlayerEventType.Hacking
|
||||
Result = PlayerEventResult.Positive
|
||||
Cooldown = 5<mins>
|
||||
IsInstigator = true
|
||||
ItemId = defaultHack.Id }
|
||||
{ Timestamp = System.DateTime.UtcNow
|
||||
Adversary = DiscordPlayer.empty
|
||||
Type = PlayerEventType.Shielding
|
||||
Result = PlayerEventResult.Positive
|
||||
Cooldown = defaultShield.Cooldown
|
||||
IsInstigator = true
|
||||
ItemId = defaultShield.Id }
|
||||
|]
|
||||
|
||||
let sendInitialEmbed (client : DiscordClient) =
|
||||
@ -156,19 +160,20 @@ let handleArsenal (ctx : IDiscordContext) =
|
||||
let hasStockWeapons = Player.getHacks player |> Array.exists (fun item -> item.Id = defaultHack.Id)
|
||||
let updatedPlayer =
|
||||
if not hasStockWeapons then {
|
||||
Player.removeExpiredActions false player with
|
||||
Player.removeExpiredActions player with
|
||||
Events = TrainerEvents |> Array.append player.Events
|
||||
Inventory = [| defaultHack ; defaultShield |] |> Array.append player.Inventory
|
||||
}
|
||||
else
|
||||
Player.removeExpiredActions false player
|
||||
Player.removeExpiredActions player
|
||||
if not hasStockWeapons then
|
||||
do! DbService.updatePlayer updatedPlayer
|
||||
let embed = Embeds.getArsenalEmbed updatedPlayer
|
||||
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
|
||||
let rewards = [ $"{defaultHack.Name} Hack" ; $"{defaultShield.Name} Shield" ]
|
||||
let embed = Embeds.getAchievementEmbed rewards "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)
|
||||
|
@ -59,7 +59,6 @@ module Types =
|
||||
}
|
||||
with static member empty = { Sell = false ; Buy = false ; Consume = false ; Drop = false }
|
||||
|
||||
|
||||
type Item = {
|
||||
Id : int
|
||||
Name : string
|
||||
@ -101,8 +100,10 @@ module Types =
|
||||
type PlayerEvent =
|
||||
{ Type : PlayerEventType
|
||||
Result : PlayerEventResult
|
||||
IsInstigator : bool
|
||||
Adversary : DiscordPlayer
|
||||
ItemId : int
|
||||
Cooldown : int<mins>
|
||||
Timestamp : DateTime }
|
||||
|
||||
[<CLIMutable>]
|
||||
|
Loading…
x
Reference in New Issue
Block a user