Refactor for new Item design
This commit is contained in:
parent
7881acab4f
commit
bf68d0ae4a
@ -108,19 +108,19 @@ let sellWeaponCommand (discordMember : DiscordMember) weaponType =
|
|||||||
]
|
]
|
||||||
track "Sell Weapon Command Invoked" discordMember.Id data
|
track "Sell Weapon Command Invoked" discordMember.Id data
|
||||||
|
|
||||||
let buyWeaponButton (discordMember : DiscordMember) (weapon : ItemDetails) =
|
let buyWeaponButton (discordMember : DiscordMember) itemName itemPrice =
|
||||||
let data = [
|
let data = [
|
||||||
"user_display_name" , discordMember.Username
|
"user_display_name" , discordMember.Username
|
||||||
"weapon_name" , weapon.Name
|
"weapon_name" , itemName
|
||||||
"weapon_price" , string weapon.Price
|
"weapon_price" , string itemPrice
|
||||||
]
|
]
|
||||||
track "Buy Weapon Button Clicked" discordMember.Id data
|
track "Buy Weapon Button Clicked" discordMember.Id data
|
||||||
|
|
||||||
let sellWeaponButton (discordMember : DiscordMember) (weapon : ItemDetails) =
|
let sellWeaponButton (discordMember : DiscordMember) (weapon : Item) price =
|
||||||
let data = [
|
let data = [
|
||||||
"user_display_name" , discordMember.Username
|
"user_display_name" , discordMember.Username
|
||||||
"weapon_name" , weapon.Name
|
"weapon_name" , weapon.Name
|
||||||
"weapon_price" , string weapon.Price
|
"weapon_price" , string price
|
||||||
]
|
]
|
||||||
track "Sell Weapon Button Clicked" discordMember.Id data
|
track "Sell Weapon Button Clicked" discordMember.Id data
|
||||||
|
|
||||||
|
@ -7,39 +7,38 @@ open Degenz
|
|||||||
open Newtonsoft.Json
|
open Newtonsoft.Json
|
||||||
|
|
||||||
module Armory =
|
module Armory =
|
||||||
let weapons : ItemDetails list =
|
let weapons : Inventory =
|
||||||
let file = System.IO.File.ReadAllText("Items.json")
|
let file = System.IO.File.ReadAllText("Items.json")
|
||||||
// let file = System.IO.File.ReadAllText("Bot/Items.json")
|
// let file = System.IO.File.ReadAllText("Bot/Items.json")
|
||||||
JsonConvert.DeserializeObject<ItemDetails array>(file)
|
JsonConvert.DeserializeObject<Inventory>(file)
|
||||||
|> Array.toList
|
|
||||||
|
|
||||||
module Inventory =
|
module Inventory =
|
||||||
let getItemsByType itemType inventory =
|
// let getItemsByType itemType inventory =
|
||||||
match itemType with
|
// match itemType with
|
||||||
| ItemType.Hack -> inventory |> List.filter (fun item -> match item with Hack _ -> true | _ -> false)
|
// | ItemType.Hack -> inventory |> List.filter (fun item -> match item with Hack _ -> true | _ -> false)
|
||||||
| ItemType.Shield -> inventory |> List.filter (fun item -> match item with Shield _ -> true | _ -> false)
|
// | ItemType.Shield -> inventory |> List.filter (fun item -> match item with Shield _ -> true | _ -> false)
|
||||||
| ItemType.Food -> inventory |> List.filter (fun item -> match item with Food _ -> true | _ -> false)
|
// | ItemType.Food -> inventory |> List.filter (fun item -> match item with Food _ -> true | _ -> false)
|
||||||
| ItemType.Accessory -> inventory |> List.filter (fun item -> match item with Accessory _ -> true | _ -> false)
|
// | ItemType.Accessory -> inventory |> List.filter (fun item -> match item with Accessory _ -> true | _ -> false)
|
||||||
|
|
||||||
let findItemById id (inventory : Inventory) = inventory |> List.find (fun item -> item.Id = id)
|
let findItemById id (inventory : Inventory) = inventory |> List.find (fun item -> item.Id = id)
|
||||||
|
|
||||||
let findHackById id inventory =
|
// let findHackById id inventory =
|
||||||
inventory |> List.pick (fun item -> match item with | Hack h -> (if h.Item.Id = id then Some h else None) | _ -> None)
|
// inventory |> List.pick (fun item -> match item with | Hack h -> (if h.Item.Id = id then Some h else None) | _ -> None)
|
||||||
let findShieldById id inventory =
|
// let findShieldById id inventory =
|
||||||
inventory |> List.pick (fun item -> match item with | Shield s -> (if s.Item.Id = id then Some s else None) | _ -> None)
|
// inventory |> List.pick (fun item -> match item with | Shield s -> (if s.Item.Id = id then Some s else None) | _ -> None)
|
||||||
let findFoodById id inventory =
|
// let findFoodById id inventory =
|
||||||
inventory |> List.pick (fun item -> match item with | Food f -> (if f.Item.Id = id then Some f else None) | _ -> None)
|
// inventory |> List.pick (fun item -> match item with | Food f -> (if f.Item.Id = id then Some f else None) | _ -> None)
|
||||||
let findAccessoryById id inventory =
|
// let findAccessoryById id inventory =
|
||||||
inventory |> List.pick (fun item -> match item with | Accessory a -> (if a.Item.Id = id then Some a else None) | _ -> None)
|
// inventory |> List.pick (fun item -> match item with | Accessory a -> (if a.Item.Id = id then Some a else None) | _ -> None)
|
||||||
|
//
|
||||||
let getHacks inventory =
|
// let getHacks inventory =
|
||||||
inventory |> List.choose (fun item -> match item with | Hack h -> Some h | _ -> None)
|
// inventory |> List.choose (fun item -> match item with | Hack h -> Some h | _ -> None)
|
||||||
let getShields inventory =
|
// let getShields inventory =
|
||||||
inventory |> List.choose (fun item -> match item with | Shield s -> Some s | _ -> None)
|
// inventory |> List.choose (fun item -> match item with | Shield s -> Some s | _ -> None)
|
||||||
let getFoods inventory =
|
// let getFoods inventory =
|
||||||
inventory |> List.choose (fun item -> match item with | Food f -> Some f | _ -> None)
|
// inventory |> List.choose (fun item -> match item with | Food f -> Some f | _ -> None)
|
||||||
let getAccessories inventory =
|
// let getAccessories inventory =
|
||||||
inventory |> List.choose (fun item -> match item with | Accessory a -> Some a | _ -> None)
|
// inventory |> List.choose (fun item -> match item with | Accessory a -> Some a | _ -> None)
|
||||||
|
|
||||||
module WeaponClass =
|
module WeaponClass =
|
||||||
let SameTargetAttackCooldown = TimeSpan.FromHours(4)
|
let SameTargetAttackCooldown = TimeSpan.FromHours(4)
|
||||||
|
115
Bot/GameTypes.fs
115
Bot/GameTypes.fs
@ -89,89 +89,51 @@ type ItemType =
|
|||||||
| Food
|
| Food
|
||||||
| Accessory
|
| Accessory
|
||||||
|
|
||||||
type ItemAttributes = {
|
type Effect =
|
||||||
CanBuy : bool
|
| Min of int
|
||||||
CanSell : bool
|
| Max of int
|
||||||
CanConsume : bool
|
| Booster of int
|
||||||
CanTrade : bool
|
| RateMultiplier of float
|
||||||
CanDrop : bool
|
|
||||||
|
type StatEffect = {
|
||||||
|
TargetStat : StatId
|
||||||
|
Effect : Effect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ItemAttribute =
|
||||||
|
| Buyable of price : int<GBT>
|
||||||
|
| Sellable of price : int<GBT>
|
||||||
|
| Expireable of lifetime : int<mins>
|
||||||
|
| Consumable of effects : StatEffect list
|
||||||
|
| Passive of effects : StatEffect list
|
||||||
|
| Droppable of chance : float
|
||||||
|
| Tradeable of yes : unit
|
||||||
|
| Attackable of power : int
|
||||||
|
| Defendable of resistance : int
|
||||||
|
| Classable of className : string
|
||||||
|
| Stackable of max : int
|
||||||
|
|
||||||
|
let (|CanBuy|_|) itemAttrs = itemAttrs |> List.tryPick (function Buyable p -> Some p | _ -> None)
|
||||||
|
let (|CanSell|_|) itemAttrs = itemAttrs |> List.tryPick (function Sellable p -> Some p | _ -> None)
|
||||||
|
let (|CanExpire|_|) itemAttrs = itemAttrs |> List.tryPick (function Expireable l -> Some l | _ -> None)
|
||||||
|
let (|CanConsume|_|) itemAttrs = itemAttrs |> List.tryPick (function Consumable es -> Some es | _ -> None)
|
||||||
|
let (|CanPassive|_|) itemAttrs = itemAttrs |> List.tryPick (function Passive es -> Some es | _ -> None)
|
||||||
|
let (|CanDrop|_|) itemAttrs = itemAttrs |> List.tryPick (function Droppable c -> Some c | _ -> None)
|
||||||
|
let (|CanTrade|_|) itemAttrs = itemAttrs |> List.tryPick (function Tradeable () -> Some () | _ -> None)
|
||||||
|
let (|CanAttack|_|) itemAttrs = itemAttrs |> List.tryPick (function Attackable p -> Some p | _ -> None)
|
||||||
|
let (|CanDefend|_|) itemAttrs = itemAttrs |> List.tryPick (function Defendable r -> Some r | _ -> None)
|
||||||
|
let (|CanClass|_|) itemAttrs = itemAttrs |> List.tryPick (function Classable c -> Some c | _ -> None)
|
||||||
|
let (|CanStack|_|) itemAttrs = itemAttrs |> List.tryPick (function Stackable m -> Some m | _ -> None)
|
||||||
|
|
||||||
|
|
||||||
type Item = {
|
type Item = {
|
||||||
Id : int
|
Id : int
|
||||||
Name : string
|
Name : string
|
||||||
Price : int<GBT>
|
Type : ItemType
|
||||||
MaxAllowed : int
|
Attributes : ItemAttribute list
|
||||||
Attributes : ItemAttributes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type HackItem = {
|
type Inventory = Item list
|
||||||
Power : int
|
|
||||||
Class : int
|
|
||||||
Cooldown : int<mins>
|
|
||||||
Item : Item
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShieldItem = {
|
|
||||||
Class : int
|
|
||||||
Cooldown : int<mins>
|
|
||||||
Item : Item
|
|
||||||
}
|
|
||||||
|
|
||||||
type FoodItem = {
|
|
||||||
TargetStat : StatId
|
|
||||||
BoostAmount : int
|
|
||||||
Item : Item
|
|
||||||
}
|
|
||||||
|
|
||||||
type AccessoryItem = {
|
|
||||||
TargetStat : StatId
|
|
||||||
FloorBoost : int
|
|
||||||
CeilBoost : int
|
|
||||||
Item : Item
|
|
||||||
}
|
|
||||||
|
|
||||||
type MeleeWeapon = {
|
|
||||||
BreakChance : float
|
|
||||||
Item : Item
|
|
||||||
}
|
|
||||||
|
|
||||||
type ItemDetails =
|
|
||||||
| Hack of HackItem
|
|
||||||
| Shield of ShieldItem
|
|
||||||
| Food of FoodItem
|
|
||||||
| Accessory of AccessoryItem
|
|
||||||
member this.Id =
|
|
||||||
match this with
|
|
||||||
| Hack i -> i.Item.Id
|
|
||||||
| Shield i -> i.Item.Id
|
|
||||||
| Food i -> i.Item.Id
|
|
||||||
| Accessory i -> i.Item.Id
|
|
||||||
member this.Name =
|
|
||||||
match this with
|
|
||||||
| Hack i -> i.Item.Name
|
|
||||||
| Shield i -> i.Item.Name
|
|
||||||
| Food i -> i.Item.Name
|
|
||||||
| Accessory i -> i.Item.Name
|
|
||||||
member this.Price =
|
|
||||||
match this with
|
|
||||||
| Hack i -> i.Item.Price
|
|
||||||
| Shield i -> i.Item.Price
|
|
||||||
| Food i -> i.Item.Price
|
|
||||||
| Accessory i -> i.Item.Price
|
|
||||||
member this.getItem =
|
|
||||||
match this with
|
|
||||||
| Hack i -> i.Item
|
|
||||||
| Shield i -> i.Item
|
|
||||||
| Food i -> i.Item
|
|
||||||
| Accessory i -> i.Item
|
|
||||||
static member getClass = function
|
|
||||||
| Hack i -> i.Class
|
|
||||||
| Shield i -> i.Class
|
|
||||||
| Food _ -> -1
|
|
||||||
| Accessory _ -> -1
|
|
||||||
|
|
||||||
type Inventory = ItemDetails list
|
|
||||||
|
|
||||||
type PlayerData = {
|
type PlayerData = {
|
||||||
DiscordId : uint64
|
DiscordId : uint64
|
||||||
@ -195,3 +157,4 @@ with member this.toDiscordPlayer = { Id = this.DiscordId ; Name = this.Name }
|
|||||||
// XP = 0
|
// XP = 0
|
||||||
Bank = 0<GBT>
|
Bank = 0<GBT>
|
||||||
Active = false }
|
Active = false }
|
||||||
|
|
||||||
|
@ -15,30 +15,33 @@ let getBuyItemsEmbed (playerInventory : Inventory) (storeInventory : Inventory)
|
|||||||
storeInventory
|
storeInventory
|
||||||
|> List.map (fun item ->
|
|> List.map (fun item ->
|
||||||
let embed = DiscordEmbedBuilder()
|
let embed = DiscordEmbedBuilder()
|
||||||
match item with
|
match item.Attributes with
|
||||||
| Hack hack ->
|
| CanBuy price -> embed.AddField("Price 💰", (if price = 0<GBT> then "Free" else $"{price} $GBT"), true) |> ignore
|
||||||
embed.AddField($"$GBT Reward |", string hack.Power, true)
|
| CanAttack power ->
|
||||||
.AddField("Cooldown |", $"{TimeSpan.FromMinutes(int hack.Cooldown).Minutes} minutes", true)
|
let title = match item.Type with ItemType.Hack -> "$GBT Reward" | _ -> "Power"
|
||||||
.WithThumbnail(Embeds.getItemIcon item.Id)
|
embed.AddField($"{title} |", string power, true) |> ignore
|
||||||
|> ignore
|
| CanExpire time ->
|
||||||
| Shield shield ->
|
let title = match item.Type with ItemType.Hack -> "Cooldown" | ItemType.Shield -> "Active For" | _ -> "Expires"
|
||||||
embed.AddField($"Strong against |", WeaponClass.getGoodAgainst shield.Class |> snd |> string, true)
|
let ts = TimeSpan.FromMinutes(int time)
|
||||||
// .AddField($"Defensive Strength |", string item.Power, true)
|
let timeStr = if ts.Hours = 0 then $"{ts.Minutes} mins" else $"{ts.Hours} hours"
|
||||||
.AddField("Active For |", $"{TimeSpan.FromMinutes(int shield.Cooldown).Hours} hours", true)
|
embed.AddField($"{title} |", timeStr, true) |> ignore
|
||||||
.WithThumbnail(Embeds.getItemIcon item.Id)
|
| CanConsume effects | CanPassive effects ->
|
||||||
|> ignore
|
let fx =
|
||||||
| Food food ->
|
effects
|
||||||
embed.AddField($"Stat |", $"{food.TargetStat}", true)
|
|> List.map (fun f ->
|
||||||
.AddField($"Amount |", $"+{food.BoostAmount}", true) |> ignore
|
match f.Effect with
|
||||||
| Accessory accessory ->
|
| Min i -> $"Min - {f.TargetStat}"
|
||||||
embed.AddField($"Stat |", $"{accessory.TargetStat}", true) |> ignore
|
| Max i -> $"Max - {f.TargetStat}"
|
||||||
if accessory.FloorBoost > 0 then
|
| Booster i ->
|
||||||
embed.AddField($"Min Boost |", $"+{accessory.FloorBoost}", true) |> ignore
|
let str = if i > 0 then "Boost" else "Penalty"
|
||||||
if accessory.CeilBoost > 0 then
|
$"{str} - {f.TargetStat}"
|
||||||
embed.AddField($"Max Boost |", $"+{accessory.CeilBoost}", true) |> ignore
|
| RateMultiplier i -> $"Multiplier - {f.TargetStat}")
|
||||||
|
|> String.concat "\n"
|
||||||
|
embed.AddField($"Effect - Amount |", $"{fx}", true) |> ignore
|
||||||
|
| _ -> ()
|
||||||
embed
|
embed
|
||||||
.AddField("Price 💰", (if item.Price = 0<GBT> then "Free" else $"{item.Price} $GBT"), true)
|
|
||||||
.WithColor(WeaponClass.getClassEmbedColor item)
|
.WithColor(WeaponClass.getClassEmbedColor item)
|
||||||
|
.WithThumbnail(Embeds.getItemIcon item.Id)
|
||||||
.WithTitle($"{item.Name}")
|
.WithTitle($"{item.Name}")
|
||||||
|> ignore
|
|> ignore
|
||||||
let button =
|
let button =
|
||||||
@ -53,47 +56,36 @@ let getBuyItemsEmbed (playerInventory : Inventory) (storeInventory : Inventory)
|
|||||||
.AddComponents(buttons)
|
.AddComponents(buttons)
|
||||||
.AsEphemeral(true)
|
.AsEphemeral(true)
|
||||||
|
|
||||||
let getSellEmbed (items : ItemDetails list) =
|
let getSellEmbed (items : Inventory) =
|
||||||
let embeds , buttons =
|
let embeds , buttons =
|
||||||
items
|
items
|
||||||
|> List.map (fun item ->
|
|> List.choose (fun item ->
|
||||||
DiscordEmbedBuilder()
|
match item.Attributes with
|
||||||
.AddField("Sell For 💰", $"{item.Price} $GBT", true)
|
| CanSell price ->
|
||||||
.WithTitle($"{item.Name}")
|
let builder =
|
||||||
.WithColor(WeaponClass.getClassEmbedColor item)
|
DiscordEmbedBuilder()
|
||||||
.Build()
|
.AddField("Sell For 💰", $"{price} $GBT", true)
|
||||||
, DiscordButtonComponent(WeaponClass.getClassButtonColor item, $"Sell-{item.Id}", $"Sell {item.Name}") :> DiscordComponent)
|
.WithTitle($"{item.Name}")
|
||||||
|> List.unzip
|
.WithColor(WeaponClass.getClassEmbedColor item)
|
||||||
|
.Build()
|
||||||
DiscordFollowupMessageBuilder()
|
let button = DiscordButtonComponent(WeaponClass.getClassButtonColor item, $"Sell-{item.Id}", $"Sell {item.Name}") :> DiscordComponent
|
||||||
.AddEmbeds(embeds)
|
Some ( builder , button )
|
||||||
.AddComponents(buttons)
|
| _ -> None)
|
||||||
.AsEphemeral(true)
|
|
||||||
|
|
||||||
let getConsumeEmbed (items : ItemDetails list) =
|
|
||||||
let embeds , buttons =
|
|
||||||
items
|
|
||||||
|> List.groupBy (fun item -> item.Id)
|
|
||||||
|> List.map (fun (itemId , items ) ->
|
|
||||||
let item = List.head items
|
|
||||||
let foodItem = Inventory.findFoodById itemId items
|
|
||||||
DiscordEmbedBuilder()
|
|
||||||
.AddField($"{foodItem.Item.Name}", $"Total {items.Length}\nBoosts {foodItem.TargetStat} +{foodItem.BoostAmount}", true)
|
|
||||||
.WithTitle($"Food Items")
|
|
||||||
.WithColor(WeaponClass.getClassEmbedColor item)
|
|
||||||
.Build()
|
|
||||||
, DiscordButtonComponent(WeaponClass.getClassButtonColor item, $"Sell-{id}", $"Sell {item.Name}") :> DiscordComponent)
|
|
||||||
|> List.unzip
|
|> List.unzip
|
||||||
|
|
||||||
|
// TODO: We should alert the user that they have no sellable items
|
||||||
DiscordFollowupMessageBuilder()
|
DiscordFollowupMessageBuilder()
|
||||||
.AddEmbeds(embeds)
|
.AddEmbeds(embeds)
|
||||||
.AddComponents(buttons)
|
.AddComponents(buttons)
|
||||||
.AsEphemeral(true)
|
.AsEphemeral(true)
|
||||||
|
|
||||||
let checkHasSufficientFunds (item : Item) player =
|
let checkHasSufficientFunds (item : Item) player =
|
||||||
if player.Bank - item.Price >= 0<GBT>
|
match item.Attributes with
|
||||||
then Ok player
|
| CanBuy price ->
|
||||||
else Error $"You do not have sufficient funds to buy this item! Current balance: {player.Bank} GBT"
|
if player.Bank - price >= 0<GBT>
|
||||||
|
then Ok player
|
||||||
|
else Error $"You do not have sufficient funds to buy this item! Current balance: {player.Bank} GBT"
|
||||||
|
| _ -> Error $"{item.Name} item cannot be bought"
|
||||||
|
|
||||||
let checkAlreadyOwnsItem (item : Item) player =
|
let checkAlreadyOwnsItem (item : Item) player =
|
||||||
if player.Inventory |> List.exists (fun w -> item.Id = w.Id)
|
if player.Inventory |> List.exists (fun w -> item.Id = w.Id)
|
||||||
@ -134,14 +126,15 @@ let handleBuyItem (ctx : IDiscordContext) itemId =
|
|||||||
executePlayerAction ctx (fun player -> async {
|
executePlayerAction ctx (fun player -> async {
|
||||||
let item = Armory.weapons |> Inventory.findItemById itemId
|
let item = Armory.weapons |> Inventory.findItemById itemId
|
||||||
do! player
|
do! player
|
||||||
|> checkHasSufficientFunds item.getItem
|
|> checkHasSufficientFunds item
|
||||||
>>= checkAlreadyOwnsItem item.getItem
|
>>= checkAlreadyOwnsItem item
|
||||||
|> handleResultWithResponse ctx (fun player -> async {
|
|> handleResultWithResponse ctx (fun player -> async {
|
||||||
let newBalance = player.Bank - item.Price
|
let price = match item.Attributes with CanBuy price -> price | _ -> 0<GBT>
|
||||||
|
let newBalance = player.Bank - price
|
||||||
let p = { player with Bank = newBalance ; Inventory = item::player.Inventory }
|
let p = { player with Bank = newBalance ; Inventory = item::player.Inventory }
|
||||||
do! DbService.updatePlayer p |> Async.Ignore
|
do! DbService.updatePlayer p |> Async.Ignore
|
||||||
do! sendFollowUpMessage ctx $"Successfully purchased {item.Name}! You now have {newBalance} 💰$GBT remaining"
|
do! sendFollowUpMessage ctx $"Successfully purchased {item.Name}! You now have {newBalance} 💰$GBT remaining"
|
||||||
do! Analytics.buyWeaponButton (ctx.GetDiscordMember()) item
|
do! Analytics.buyWeaponButton (ctx.GetDiscordMember()) item.Name price
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -150,20 +143,23 @@ let handleSell (ctx : IDiscordContext) itemId =
|
|||||||
let item = Armory.weapons |> Inventory.findItemById itemId
|
let item = Armory.weapons |> Inventory.findItemById itemId
|
||||||
do!
|
do!
|
||||||
player
|
player
|
||||||
|> checkSoldItemAlready item.getItem
|
|> checkSoldItemAlready item
|
||||||
|> handleResultWithResponse ctx (fun player -> async {
|
|> handleResultWithResponse ctx (fun player -> async {
|
||||||
let updatedPlayer = {
|
match item.Attributes with
|
||||||
player with
|
| CanSell price ->
|
||||||
Bank = player.Bank + item.Price
|
let updatedPlayer = {
|
||||||
Inventory = player.Inventory |> List.filter (fun i -> i.Id <> itemId)
|
player with
|
||||||
}
|
Bank = player.Bank + price
|
||||||
do!
|
Inventory = player.Inventory |> List.filter (fun i -> i.Id <> itemId)
|
||||||
[ DbService.updatePlayer updatedPlayer |> Async.Ignore
|
}
|
||||||
DbService.removeShieldEvent updatedPlayer.DiscordId itemId |> Async.Ignore
|
do!
|
||||||
sendFollowUpMessage ctx $"Sold {item.Name} for {item.Price}! Current Balance: {updatedPlayer.Bank}"
|
[ DbService.updatePlayer updatedPlayer |> Async.Ignore
|
||||||
Analytics.sellWeaponButton (ctx.GetDiscordMember()) item ]
|
DbService.removeShieldEvent updatedPlayer.DiscordId itemId |> Async.Ignore
|
||||||
|> Async.Parallel
|
sendFollowUpMessage ctx $"Sold {item.Name} for {price}! Current Balance: {updatedPlayer.Bank}"
|
||||||
|> Async.Ignore
|
Analytics.sellWeaponButton (ctx.GetDiscordMember()) item price ]
|
||||||
|
|> Async.Parallel
|
||||||
|
|> Async.Ignore
|
||||||
|
| _ -> ()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -187,33 +183,33 @@ let showInventoryEmbed (ctx : IDiscordContext) = PlayerInteractions.executePlaye
|
|||||||
player.Inventory
|
player.Inventory
|
||||||
|> List.map (fun item ->
|
|> List.map (fun item ->
|
||||||
let embed = DiscordEmbedBuilder()
|
let embed = DiscordEmbedBuilder()
|
||||||
match item with
|
match item.Attributes with
|
||||||
| Hack hack ->
|
| CanBuy price -> embed.AddField("Price 💰", (if price = 0<GBT> then "Free" else $"{price} $GBT"), true) |> ignore
|
||||||
embed.AddField($"$GBT Reward |", string hack.Power, true)
|
| CanAttack power ->
|
||||||
.AddField("Cooldown |", $"{TimeSpan.FromMinutes(int hack.Cooldown).Minutes} minutes", true)
|
let title = match item.Type with ItemType.Hack -> "$GBT Reward" | _ -> "Power"
|
||||||
.WithColor(DiscordColor.Red)
|
embed.AddField($"{title} |", string power, true) |> ignore
|
||||||
.WithThumbnail(Embeds.getItemIcon item.Id)
|
| CanExpire time ->
|
||||||
|> ignore
|
let title = match item.Type with ItemType.Hack -> "Cooldown" | ItemType.Shield -> "Active For" | _ -> "Expires"
|
||||||
| Shield shield ->
|
let ts = TimeSpan.FromMinutes(int time)
|
||||||
embed.AddField($"Strong against |", WeaponClass.getGoodAgainst shield.Class |> snd |> string, true)
|
let timeStr = if ts.Hours = 0 then $"{ts.Minutes} mins" else $"{ts.Hours} hours"
|
||||||
// .AddField($"Defensive Strength |", string item.Power, true)
|
embed.AddField($"{title} |", timeStr, true) |> ignore
|
||||||
.AddField("Active For |", $"{TimeSpan.FromMinutes(int shield.Cooldown).Hours} hours", true)
|
| CanConsume effects | CanPassive effects ->
|
||||||
.WithColor(DiscordColor.SapGreen)
|
let fx =
|
||||||
.WithThumbnail(Embeds.getItemIcon item.Id)
|
effects
|
||||||
|> ignore
|
|> List.map (fun f ->
|
||||||
| Food food ->
|
match f.Effect with
|
||||||
embed.AddField($"Stat |", $"{food.TargetStat}", true)
|
| Min i -> $"Min - {f.TargetStat}"
|
||||||
.WithColor(DiscordColor.Azure)
|
| Max i -> $"Max - {f.TargetStat}"
|
||||||
.AddField($"Amount |", $"+{food.BoostAmount}", true) |> ignore
|
| Booster i ->
|
||||||
| Accessory accessory ->
|
let str = if i > 0 then "Boost" else "Penalty"
|
||||||
embed.AddField($"Stat |", $"{accessory.TargetStat}", true)
|
$"{str} - {f.TargetStat}"
|
||||||
.WithColor(DiscordColor.Goldenrod) |> ignore
|
| RateMultiplier i -> $"Multiplier - {f.TargetStat}")
|
||||||
if accessory.FloorBoost > 0 then
|
|> String.concat "\n"
|
||||||
embed.AddField($"Min Boost |", $"+{accessory.FloorBoost}", true) |> ignore
|
embed.AddField($"Effect - Amount |", $"{fx}", true) |> ignore
|
||||||
if accessory.CeilBoost > 0 then
|
| _ -> ()
|
||||||
embed.AddField($"Max Boost |", $"+{accessory.CeilBoost}", true) |> ignore
|
|
||||||
embed
|
embed
|
||||||
.AddField("Price 💰", (if item.Price = 0<GBT> then "Free" else $"{item.Price} $GBT"), true)
|
.WithColor(WeaponClass.getClassEmbedColor item)
|
||||||
|
.WithThumbnail(Embeds.getItemIcon item.Id)
|
||||||
.WithTitle($"{item.Name}")
|
.WithTitle($"{item.Name}")
|
||||||
|> ignore
|
|> ignore
|
||||||
let button =
|
let button =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user