Store for food and accessory items, read stats
This commit is contained in:
parent
05cdb98bee
commit
8a57d3305e
@ -78,14 +78,16 @@ let tryFindPlayer (discordId : uint64) = async {
|
|||||||
SELECT discord_id, display_name, gbt, inventory, strength, focus, charisma, luck FROM "user"
|
SELECT discord_id, display_name, gbt, inventory, strength, focus, charisma, luck FROM "user"
|
||||||
WHERE discord_id = @did
|
WHERE discord_id = @did
|
||||||
"""
|
"""
|
||||||
|> Sql.executeAsync (fun read -> {
|
|> Sql.executeAsync (fun read ->
|
||||||
|
let inv = read.intArray "inventory"
|
||||||
|
{
|
||||||
DiscordId = read.string "discord_id" |> uint64
|
DiscordId = read.string "discord_id" |> uint64
|
||||||
Name = read.string "display_name"
|
Name = read.string "display_name"
|
||||||
Bank = read.int "gbt" * 1<GBT>
|
Bank = read.int "gbt" * 1<GBT>
|
||||||
Inventory = read.intArray "inventory" |> Array.toList
|
Inventory = inv |> Array.toList
|
||||||
Strength = read.int "strength"
|
Strength = read.int "strength"
|
||||||
Focus = read.int "focus"
|
Focus = read.int "focus"
|
||||||
Charisma = read.int "charm"
|
Charisma = read.int "charisma"
|
||||||
Luck = read.int "luck"
|
Luck = read.int "luck"
|
||||||
})
|
})
|
||||||
|> Async.AwaitTask
|
|> Async.AwaitTask
|
||||||
|
@ -33,7 +33,7 @@ let constructButtons (actionId: string) (buttonInfo : string) (player: PlayerDat
|
|||||||
|> List.map (fun item ->
|
|> List.map (fun item ->
|
||||||
let action =
|
let action =
|
||||||
player.Events
|
player.Events
|
||||||
|> Array.tryFind (fun i ->
|
|> List.tryFind (fun i ->
|
||||||
match i.Type with
|
match i.Type with
|
||||||
| Hacking h -> h.HackId = item.Id && h.IsInstigator
|
| Hacking h -> h.HackId = item.Id && h.IsInstigator
|
||||||
| Shielding id -> id = item.Id
|
| Shielding id -> id = item.Id
|
||||||
@ -101,7 +101,7 @@ let responseSuccessfulHack earnedMoney (targetId : uint64) amountTaken (hack : H
|
|||||||
let responseCreatedShield (shield : ShieldItem) =
|
let responseCreatedShield (shield : ShieldItem) =
|
||||||
let embed = DiscordEmbedBuilder().WithImageUrl(getItemGif shield.Id)
|
let embed = DiscordEmbedBuilder().WithImageUrl(getItemGif shield.Id)
|
||||||
embed.Title <- "Mounted Shield"
|
embed.Title <- "Mounted Shield"
|
||||||
embed.Description <- $"Mounted {shield.Name} shield for {TimeSpan.FromMinutes(int shield.Cooldown).Hours} hours"
|
embed.Description <- $"Mounted {shield.Name} shield for {TimeSpan.FromMinutes(int shield.Cooldown).TotalHours} hours"
|
||||||
|
|
||||||
DiscordFollowupMessageBuilder()
|
DiscordFollowupMessageBuilder()
|
||||||
.AddEmbed(embed)
|
.AddEmbed(embed)
|
||||||
|
@ -21,7 +21,6 @@ module Inventory =
|
|||||||
Class = hackClass
|
Class = hackClass
|
||||||
Cooldown = cooldown
|
Cooldown = cooldown
|
||||||
}
|
}
|
||||||
|
|
||||||
let itemToShield item hackClass cooldown = {
|
let itemToShield item hackClass cooldown = {
|
||||||
Id = item.Id
|
Id = item.Id
|
||||||
Name = item.Name
|
Name = item.Name
|
||||||
@ -29,31 +28,48 @@ module Inventory =
|
|||||||
Class = hackClass
|
Class = hackClass
|
||||||
Cooldown = cooldown
|
Cooldown = cooldown
|
||||||
}
|
}
|
||||||
|
let itemToFood item targetStat boostAmount = {
|
||||||
|
Id = item.Id
|
||||||
|
Name = item.Name
|
||||||
|
Price = item.Price
|
||||||
|
TargetStat = targetStat
|
||||||
|
BoostAmount = boostAmount
|
||||||
|
}
|
||||||
let hackToItem (hack : HackItem) = {
|
let hackToItem (hack : HackItem) = {
|
||||||
Id = hack.Id
|
Id = hack.Id
|
||||||
Name = hack.Name
|
Name = hack.Name
|
||||||
Price = hack.Price
|
Price = hack.Price
|
||||||
Type = Hack (hack.Power, hack.Class, hack.Cooldown)
|
Details = Hack (hack.Power, hack.Class, hack.Cooldown)
|
||||||
}
|
}
|
||||||
let shieldToItem (shield : ShieldItem) = {
|
let shieldToItem (shield : ShieldItem) = {
|
||||||
Id = shield.Id
|
Id = shield.Id
|
||||||
Name = shield.Name
|
Name = shield.Name
|
||||||
Price = shield.Price
|
Price = shield.Price
|
||||||
Type = Shield (shield.Class, shield.Cooldown)
|
Details = Shield (shield.Class, shield.Cooldown)
|
||||||
}
|
}
|
||||||
|
|
||||||
let filterByHacks inventory =
|
let filterByHacks inventory =
|
||||||
inventory |> List.filter (fun item -> match item.Type with Hack _ -> true | _ -> false)
|
inventory |> List.filter (fun item -> match item.Details with Hack _ -> true | _ -> false)
|
||||||
let filterByShields inventory =
|
let filterByShields inventory =
|
||||||
inventory |> List.filter (fun item -> match item.Type with Shield _ -> true | _ -> false)
|
inventory |> List.filter (fun item -> match item.Details with Shield _ -> true | _ -> false)
|
||||||
|
let filterByWeapons inventory =
|
||||||
|
inventory |> List.filter (fun item -> match item.Details with Hack _ | Shield _ -> true | _ -> false)
|
||||||
|
let filterByFood inventory =
|
||||||
|
inventory |> List.filter (fun item -> match item.Details with Food _ -> true | _ -> false)
|
||||||
|
let filterByAccessories inventory =
|
||||||
|
inventory |> List.filter (fun item -> match item.Details with Accessory _ -> true | _ -> false)
|
||||||
|
|
||||||
let getHackItems inventory =
|
let getHackItems inventory =
|
||||||
inventory
|
inventory
|
||||||
|> List.choose (fun item -> match item.Type with Hack (p,cl,co) -> Some (itemToHack item p cl co) | _ -> None)
|
|> List.choose (fun item -> match item.Details with Hack (p,cl,co) -> Some (itemToHack item p cl co) | _ -> None)
|
||||||
|> List.sortBy (fun item -> item.Id)
|
|> List.sortBy (fun item -> item.Id)
|
||||||
let getShieldItems inventory =
|
let getShieldItems inventory =
|
||||||
inventory
|
inventory
|
||||||
|> List.choose (fun item -> match item.Type with Shield (cl,co) -> Some (itemToShield item cl co) | _ -> None)
|
|> List.choose (fun item -> match item.Details with Shield (cl,co) -> Some (itemToShield item cl co) | _ -> None)
|
||||||
|
|> List.sortBy (fun item -> item.Id)
|
||||||
|
let getFoodItems inventory =
|
||||||
|
inventory
|
||||||
|
|> List.choose (fun item -> match item.Details with Food(t,b) -> Some (itemToFood item t b) | _ -> None)
|
||||||
|> List.sortBy (fun item -> item.Id)
|
|> List.sortBy (fun item -> item.Id)
|
||||||
let findItemById id inventory = inventory |> List.find (fun item -> item.Id = id)
|
let findItemById id inventory = inventory |> List.find (fun item -> item.Id = id)
|
||||||
let tryFindItemById id inventory = inventory |> List.tryFind (fun item -> item.Id = id)
|
let tryFindItemById id inventory = inventory |> List.tryFind (fun item -> item.Id = id)
|
||||||
@ -61,6 +77,8 @@ module Inventory =
|
|||||||
inventory |> getHackItems |> List.pick (fun item -> if item.Id = id then Some item else None)
|
inventory |> getHackItems |> List.pick (fun item -> if item.Id = id then Some item else None)
|
||||||
let findShieldById id inventory =
|
let findShieldById id inventory =
|
||||||
inventory |> getShieldItems |> List.pick (fun item -> if item.Id = id then Some item else None)
|
inventory |> getShieldItems |> List.pick (fun item -> if item.Id = id then Some item else None)
|
||||||
|
let findFoodById id inventory =
|
||||||
|
inventory |> getFoodItems |> List.pick (fun item -> if item.Id = id then Some item else None)
|
||||||
let tryFindHackById id inventory =
|
let tryFindHackById id inventory =
|
||||||
inventory |> getHackItems |> List.tryFind (fun item -> item.Id = id)
|
inventory |> getHackItems |> List.tryFind (fun item -> item.Id = id)
|
||||||
let tryFindShieldById id inventory =
|
let tryFindShieldById id inventory =
|
||||||
@ -70,14 +88,14 @@ module WeaponClass =
|
|||||||
let SameTargetAttackCooldown = System.TimeSpan.FromHours(1)
|
let SameTargetAttackCooldown = System.TimeSpan.FromHours(1)
|
||||||
|
|
||||||
let getClassButtonColor item =
|
let getClassButtonColor item =
|
||||||
match item.Type with
|
match item.Details with
|
||||||
| Hack (_,0,_) | Shield (0,_) -> ButtonStyle.Danger
|
| Hack (_,0,_) | Shield (0,_) -> ButtonStyle.Danger
|
||||||
| Hack (_,1,_) | Shield (1,_) -> ButtonStyle.Primary
|
| Hack (_,1,_) | Shield (1,_) -> ButtonStyle.Primary
|
||||||
| Hack (_,2,_) | Shield (2,_) -> ButtonStyle.Success
|
| Hack (_,2,_) | Shield (2,_) -> ButtonStyle.Success
|
||||||
| _ -> ButtonStyle.Primary
|
| _ -> ButtonStyle.Primary
|
||||||
|
|
||||||
let getClassEmbedColor item =
|
let getClassEmbedColor item =
|
||||||
match item.Type with
|
match item.Details with
|
||||||
| Hack (_,0,_) | Shield (0,_) -> DiscordColor.Red
|
| Hack (_,0,_) | Shield (0,_) -> DiscordColor.Red
|
||||||
| Hack (_,1,_) | Shield (1,_) -> DiscordColor.Blurple
|
| Hack (_,1,_) | Shield (1,_) -> DiscordColor.Blurple
|
||||||
| Hack (_,2,_) | Shield (2,_) -> DiscordColor.Green
|
| Hack (_,2,_) | Shield (2,_) -> DiscordColor.Green
|
||||||
@ -120,8 +138,8 @@ module PlayerStats =
|
|||||||
// let hoursElapsed = (DateTime.UtcNow - lastRead).Hours
|
// let hoursElapsed = (DateTime.UtcNow - lastRead).Hours
|
||||||
// let totalDecay = float hoursElapsed * statConfig.BaseDecayRate
|
// let totalDecay = float hoursElapsed * statConfig.BaseDecayRate
|
||||||
let modMinMax =
|
let modMinMax =
|
||||||
let min = items |> List.sumBy (fun item -> match item.Type with | Accessory(_,floorBoost,_) -> floorBoost | _ -> 0)
|
let min = items |> List.sumBy (fun item -> match item.Details with | Accessory(_,floorBoost,_) -> floorBoost | _ -> 0)
|
||||||
let max = items |> List.sumBy (fun item -> match item.Type with | Accessory(_,_,ceilBoost) -> ceilBoost | _ -> 0)
|
let max = items |> List.sumBy (fun item -> match item.Details with | Accessory(_,_,ceilBoost) -> ceilBoost | _ -> 0)
|
||||||
Range.create (statConfig.BaseRange.Min + min) (statConfig.BaseRange.Max + max)
|
Range.create (statConfig.BaseRange.Min + min) (statConfig.BaseRange.Max + max)
|
||||||
let amountAfterDecay = modMinMax |> Range.constrain amount
|
let amountAfterDecay = modMinMax |> Range.constrain amount
|
||||||
{ Id = statId ; Amount = amountAfterDecay ; ModRange = modMinMax ; LastRead = DateTime.UtcNow }
|
{ Id = statId ; Amount = amountAfterDecay ; ModRange = modMinMax ; LastRead = DateTime.UtcNow }
|
||||||
|
@ -24,12 +24,16 @@ type ItemId =
|
|||||||
| Firewall = 6
|
| Firewall = 6
|
||||||
| Encryption = 7
|
| Encryption = 7
|
||||||
| Cypher = 8
|
| Cypher = 8
|
||||||
|
| ProteinPowder = 12
|
||||||
|
| ToroLoco = 13
|
||||||
|
| Cigs = 14
|
||||||
|
| MoonPie = 15
|
||||||
|
|
||||||
type StatId =
|
type StatId =
|
||||||
| Strength = 0
|
| Strength = 0
|
||||||
| Focus = 1
|
| Focus = 1
|
||||||
| Luck = 2
|
| Charisma = 2
|
||||||
| Charisma = 3
|
| Luck = 3
|
||||||
|
|
||||||
type StatConfig = {
|
type StatConfig = {
|
||||||
Id : StatId
|
Id : StatId
|
||||||
@ -112,7 +116,14 @@ type AccessoryItem = {
|
|||||||
CeilBoost : int
|
CeilBoost : int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[<RequireQualifiedAccess>]
|
||||||
type ItemType =
|
type ItemType =
|
||||||
|
| Hack
|
||||||
|
| Shield
|
||||||
|
| Food
|
||||||
|
| Accessory
|
||||||
|
|
||||||
|
type ItemDetails =
|
||||||
| Hack of power : int * hackClass : int * cooldown : int<mins>
|
| Hack of power : int * hackClass : int * cooldown : int<mins>
|
||||||
| Shield of shieldClass : int * cooldown : int<mins>
|
| Shield of shieldClass : int * cooldown : int<mins>
|
||||||
| Food of targetStat : StatId * boostAmount : int
|
| Food of targetStat : StatId * boostAmount : int
|
||||||
@ -121,7 +132,8 @@ and Item = {
|
|||||||
Id : int
|
Id : int
|
||||||
Name : string
|
Name : string
|
||||||
Price : int<GBT>
|
Price : int<GBT>
|
||||||
Type : ItemType
|
// Type : ItemType
|
||||||
|
Details : ItemDetails
|
||||||
}
|
}
|
||||||
and Inventory = Item list
|
and Inventory = Item list
|
||||||
and PlayerData = {
|
and PlayerData = {
|
||||||
|
@ -19,7 +19,7 @@ let checkAlreadyHackedTarget defender attacker =
|
|||||||
defender
|
defender
|
||||||
|> Player.removeExpiredActions
|
|> Player.removeExpiredActions
|
||||||
|> fun d -> d.Events
|
|> fun d -> d.Events
|
||||||
|> Array.tryFind (fun event ->
|
|> List.tryFind (fun event ->
|
||||||
match event.Type with
|
match event.Type with
|
||||||
| Hacking h -> h.Adversary.Id = attacker.DiscordId && h.IsInstigator = false
|
| Hacking h -> h.Adversary.Id = attacker.DiscordId && h.IsInstigator = false
|
||||||
| _ -> false)
|
| _ -> false)
|
||||||
@ -32,7 +32,7 @@ let checkAlreadyHackedTarget defender attacker =
|
|||||||
|
|
||||||
let checkWeaponHasCooldown (weapon : Item) attacker =
|
let checkWeaponHasCooldown (weapon : Item) attacker =
|
||||||
attacker.Events
|
attacker.Events
|
||||||
|> Array.tryFind (fun a ->
|
|> List.tryFind (fun a ->
|
||||||
match a.Type with
|
match a.Type with
|
||||||
| Hacking h -> h.HackId = weapon.Id && h.IsInstigator
|
| Hacking h -> h.HackId = weapon.Id && h.IsInstigator
|
||||||
| Shielding id -> id = weapon.Id
|
| Shielding id -> id = weapon.Id
|
||||||
@ -56,9 +56,9 @@ let checkPlayerOwnsWeapon (item : Item) player =
|
|||||||
let checkPlayerHasShieldSlotsAvailable player =
|
let checkPlayerHasShieldSlotsAvailable player =
|
||||||
let updatedPlayer = player |> Player.removeExpiredActions
|
let updatedPlayer = player |> Player.removeExpiredActions
|
||||||
let defenses = Player.getShieldEvents updatedPlayer
|
let defenses = Player.getShieldEvents updatedPlayer
|
||||||
match defenses |> Array.length >= 3 with
|
match defenses |> List.length >= 3 with
|
||||||
| true ->
|
| true ->
|
||||||
let event = defenses |> Array.rev |> Array.head // This should be the next expiring timestamp
|
let event = defenses |> List.rev |> List.head // This should be the next expiring timestamp
|
||||||
let cooldown = getTimeText true (TimeSpan.FromMinutes(int event.Cooldown)) event.Timestamp
|
let cooldown = getTimeText true (TimeSpan.FromMinutes(int event.Cooldown)) event.Timestamp
|
||||||
Error $"You are only allowed three shields at a time. Wait {cooldown} to add another shield"
|
Error $"You are only allowed three shields at a time. Wait {cooldown} to add another shield"
|
||||||
| false -> Ok updatedPlayer
|
| false -> Ok updatedPlayer
|
||||||
@ -72,16 +72,16 @@ let runHackerBattle defender (hack : HackItem) =
|
|||||||
defender
|
defender
|
||||||
|> Player.removeExpiredActions
|
|> Player.removeExpiredActions
|
||||||
|> fun p -> p.Events
|
|> fun p -> p.Events
|
||||||
|> Array.choose (fun event ->
|
|> List.choose (fun event ->
|
||||||
match event.Type with
|
match event.Type with
|
||||||
| Shielding id -> defender.Inventory |> Inventory.getShieldItems |> List.find (fun item -> item.Id = id) |> Some
|
| Shielding id -> defender.Inventory |> Inventory.getShieldItems |> List.find (fun item -> item.Id = id) |> Some
|
||||||
| _ -> None)
|
| _ -> None)
|
||||||
|> Array.map (fun shield -> if hack.Class = shield.Class then Weak else Strong)
|
|> List.map (fun shield -> if hack.Class = shield.Class then Weak else Strong)
|
||||||
|> Array.contains Weak
|
|> List.contains Weak
|
||||||
|
|
||||||
let updateCombatants successfulHack (attacker : PlayerData) (defender : PlayerData) (hack : HackItem) prize =
|
let updateCombatants successfulHack (attacker : PlayerData) (defender : PlayerData) (hack : HackItem) prize =
|
||||||
let updatePlayer amount attack p =
|
let updatePlayer amount attack p =
|
||||||
{ p with Events = Array.append [| attack |] p.Events ; Bank = max (p.Bank + amount) 0<GBT> }
|
{ p with Events = attack::p.Events ; Bank = max (p.Bank + amount) 0<GBT> }
|
||||||
let event isDefenderEvent =
|
let event isDefenderEvent =
|
||||||
let hackEvent = {
|
let hackEvent = {
|
||||||
HackId = hack.Id
|
HackId = hack.Id
|
||||||
|
@ -15,7 +15,7 @@ let getBuyItemsEmbed (playerInventory : Inventory) (storeInventory : Inventory)
|
|||||||
storeInventory
|
storeInventory
|
||||||
|> List.map (fun item ->
|
|> List.map (fun item ->
|
||||||
let embed = DiscordEmbedBuilder()
|
let embed = DiscordEmbedBuilder()
|
||||||
match item.Type with
|
match item.Details with
|
||||||
| Hack(power,_,cooldown) ->
|
| Hack(power,_,cooldown) ->
|
||||||
embed.AddField($"$GBT Reward |", string power, true)
|
embed.AddField($"$GBT Reward |", string power, true)
|
||||||
.AddField("Cooldown |", $"{TimeSpan.FromMinutes(int cooldown).Minutes} minutes", true)
|
.AddField("Cooldown |", $"{TimeSpan.FromMinutes(int cooldown).Minutes} minutes", true)
|
||||||
@ -27,7 +27,15 @@ let getBuyItemsEmbed (playerInventory : Inventory) (storeInventory : Inventory)
|
|||||||
.AddField("Active For |", $"{TimeSpan.FromMinutes(int cooldown).Hours} hours", true)
|
.AddField("Active For |", $"{TimeSpan.FromMinutes(int cooldown).Hours} hours", true)
|
||||||
.WithThumbnail(Embeds.getItemIcon item.Id)
|
.WithThumbnail(Embeds.getItemIcon item.Id)
|
||||||
|> ignore
|
|> ignore
|
||||||
| _ -> ()
|
| Food(targetStat, boostAmount) ->
|
||||||
|
embed.AddField($"Stat |", $"{targetStat}", true)
|
||||||
|
.AddField($"Amount |", $"+{boostAmount}", true) |> ignore
|
||||||
|
| Accessory(targetStat, floorBoost, ceilBoost) ->
|
||||||
|
embed.AddField($"Stat |", $"{targetStat}", true) |> ignore
|
||||||
|
if floorBoost > 0 then
|
||||||
|
embed.AddField($"Min Boost |", $"+{floorBoost}", true) |> ignore
|
||||||
|
if ceilBoost > 0 then
|
||||||
|
embed.AddField($"Max Boost |", $"+{ceilBoost}", true) |> ignore
|
||||||
embed
|
embed
|
||||||
.AddField("Price 💰", (if item.Price = 0<GBT> then "Free" else $"{item.Price} $GBT"), true)
|
.AddField("Price 💰", (if item.Price = 0<GBT> then "Free" else $"{item.Price} $GBT"), true)
|
||||||
.WithColor(WeaponClass.getClassEmbedColor item)
|
.WithColor(WeaponClass.getClassEmbedColor item)
|
||||||
@ -62,6 +70,26 @@ let getSellEmbed (items : Item list) =
|
|||||||
.AddComponents(buttons)
|
.AddComponents(buttons)
|
||||||
.AsEphemeral(true)
|
.AsEphemeral(true)
|
||||||
|
|
||||||
|
let getConsumeEmbed (items : Item 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.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
|
||||||
|
|
||||||
|
DiscordFollowupMessageBuilder()
|
||||||
|
.AddEmbeds(embeds)
|
||||||
|
.AddComponents(buttons)
|
||||||
|
.AsEphemeral(true)
|
||||||
|
|
||||||
let checkHasSufficientFunds (item : Item) player =
|
let checkHasSufficientFunds (item : Item) player =
|
||||||
if player.Bank - item.Price >= 0<GBT>
|
if player.Bank - item.Price >= 0<GBT>
|
||||||
then Ok player
|
then Ok player
|
||||||
@ -127,12 +155,24 @@ let handleSell (ctx : IDiscordContext) itemId =
|
|||||||
do!
|
do!
|
||||||
[ DbService.updatePlayer updatedPlayer |> Async.Ignore
|
[ DbService.updatePlayer updatedPlayer |> Async.Ignore
|
||||||
DbService.removeShieldEvent updatedPlayer.DiscordId itemId |> Async.Ignore
|
DbService.removeShieldEvent updatedPlayer.DiscordId itemId |> Async.Ignore
|
||||||
sendFollowUpMessage ctx $"Sold {item.Type} {item.Name} for {item.Price}! Current Balance: {updatedPlayer.Bank}" ]
|
sendFollowUpMessage ctx $"Sold {item.Details} {item.Name} for {item.Price}! Current Balance: {updatedPlayer.Bank}" ]
|
||||||
|> Async.Parallel
|
|> Async.Parallel
|
||||||
|> Async.Ignore
|
|> Async.Ignore
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//let inventory (ctx : IDiscordContext) =
|
||||||
|
// executePlayerAction ctx (fun player -> async {
|
||||||
|
// player.Inventory
|
||||||
|
// |> List.groupBy (fun item -> item.Details)
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//let consume (ctx : IDiscordContext) =
|
||||||
|
// executePlayerAction ctx (fun player -> async {
|
||||||
|
//
|
||||||
|
// })
|
||||||
|
|
||||||
let handleStoreEvents (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
let handleStoreEvents (_ : DiscordClient) (event : ComponentInteractionCreateEventArgs) =
|
||||||
let ctx = DiscordEventContext event :> IDiscordContext
|
let ctx = DiscordEventContext event :> IDiscordContext
|
||||||
let id = ctx.GetInteractionId()
|
let id = ctx.GetInteractionId()
|
||||||
@ -160,15 +200,38 @@ type Store() =
|
|||||||
do! Messaging.sendSimpleResponse ctx msg
|
do! Messaging.sendSimpleResponse ctx msg
|
||||||
}
|
}
|
||||||
|
|
||||||
[<SlashCommand("buy-hack", "Purchase a hack attack you can use to earn GoodBoyTokenz")>]
|
let checkChannel (ctx : IDiscordContext) =
|
||||||
member _.BuyHack (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (buy Inventory.filterByHacks)
|
match ctx.GetChannel().Id with
|
||||||
|
| id when id = GuildEnvironment.channelBackAlley -> buy Inventory.filterByHacks ctx
|
||||||
|
| id when id = GuildEnvironment.channelArmory -> buy Inventory.filterByShields ctx
|
||||||
|
| id when id = GuildEnvironment.channelMarket -> buy Inventory.filterByFood ctx
|
||||||
|
| id when id = GuildEnvironment.channelAccessoryShop -> buy Inventory.filterByAccessories ctx
|
||||||
|
| _ ->
|
||||||
|
task {
|
||||||
|
let msg = $"This channel doesn't have any items to sell"
|
||||||
|
do! Messaging.sendSimpleResponse ctx msg
|
||||||
|
}
|
||||||
|
|
||||||
|
[<SlashCommand("buy-item", "Purchase an item")>]
|
||||||
|
member _.BuyItem (ctx : InteractionContext) = checkChannel (DiscordInteractionContext(ctx))
|
||||||
|
|
||||||
[<SlashCommand("buy-shield", "Purchase a hack shield so you can protect your GoodBoyTokenz")>]
|
[<SlashCommand("buy-shield", "Purchase a hack shield so you can protect your GoodBoyTokenz")>]
|
||||||
member this.BuyShield (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (buy Inventory.filterByShields)
|
member this.BuyShield (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (buy Inventory.filterByShields)
|
||||||
|
|
||||||
|
[<SlashCommand("buy-food", "Purchase a food item to help boost your stats")>]
|
||||||
|
member this.BuyFood (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (buy Inventory.filterByFood)
|
||||||
|
|
||||||
[<SlashCommand("sell-hack", "Sell a hack for GoodBoyTokenz")>]
|
[<SlashCommand("sell-hack", "Sell a hack for GoodBoyTokenz")>]
|
||||||
member this.SellHack (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (sell "Hacks" Inventory.filterByHacks)
|
member this.SellHack (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (sell "Hacks" Inventory.filterByHacks)
|
||||||
|
|
||||||
[<SlashCommand("sell-shield", "Sell a shield for GoodBoyTokenz")>]
|
[<SlashCommand("sell-shield", "Sell a shield for GoodBoyTokenz")>]
|
||||||
member this.SellShield (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (sell "Shields" Inventory.filterByShields)
|
member this.SellShield (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (sell "Shields" Inventory.filterByShields)
|
||||||
|
|
||||||
|
[<SlashCommand("consume", "Consume a food item")>]
|
||||||
|
member this.Consume (ctx : InteractionContext) =
|
||||||
|
enforceChannel (DiscordInteractionContext(ctx)) (sell "Shields" Inventory.filterByShields)
|
||||||
|
|
||||||
|
[<SlashCommand("inventory", "Check your inventory")>]
|
||||||
|
member this.Inventory (ctx : InteractionContext) =
|
||||||
|
enforceChannel (DiscordInteractionContext(ctx)) (sell "Shields" Inventory.filterByShields)
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ let checkVictimStealingCooldown defender attacker =
|
|||||||
defender
|
defender
|
||||||
|> Player.removeExpiredActions
|
|> Player.removeExpiredActions
|
||||||
|> fun p -> p.Events
|
|> fun p -> p.Events
|
||||||
|> Array.tryFind (fun e ->
|
|> List.tryFind (fun e ->
|
||||||
match e.Type with Stealing _ -> true | _ -> false)
|
match e.Type with Stealing _ -> true | _ -> false)
|
||||||
|> function
|
|> function
|
||||||
| Some act ->
|
| Some act ->
|
||||||
@ -95,7 +95,7 @@ let checkThiefCooldown attacker =
|
|||||||
attacker
|
attacker
|
||||||
|> Player.removeExpiredActions
|
|> Player.removeExpiredActions
|
||||||
|> fun p -> p.Events
|
|> fun p -> p.Events
|
||||||
|> Array.tryFind (fun pe -> match pe.Type with Stealing(instigator, _) -> instigator | _ -> false)
|
|> List.tryFind (fun pe -> match pe.Type with Stealing(instigator, _) -> instigator | _ -> false)
|
||||||
|> function
|
|> function
|
||||||
| Some act ->
|
| Some act ->
|
||||||
let cooldown = ThiefCooldown - (DateTime.UtcNow - act.Timestamp)
|
let cooldown = ThiefCooldown - (DateTime.UtcNow - act.Timestamp)
|
||||||
|
@ -12,7 +12,7 @@ let Sensei = { Id = GuildEnvironment.botIdHackerBattle ; Name = "Sensei" }
|
|||||||
let defaultHack = Armory.weapons |> Inventory.findHackById (int ItemId.Virus)
|
let defaultHack = Armory.weapons |> Inventory.findHackById (int ItemId.Virus)
|
||||||
let defaultShield = Armory.weapons |> Inventory.findShieldById (int ItemId.Firewall)
|
let defaultShield = Armory.weapons |> Inventory.findShieldById (int ItemId.Firewall)
|
||||||
|
|
||||||
let TrainerEvents = [|
|
let TrainerEvents = [
|
||||||
{ Timestamp = System.DateTime.UtcNow
|
{ Timestamp = System.DateTime.UtcNow
|
||||||
Cooldown = defaultHack.Cooldown
|
Cooldown = defaultHack.Cooldown
|
||||||
Type = Hacking {
|
Type = Hacking {
|
||||||
@ -23,7 +23,7 @@ let TrainerEvents = [|
|
|||||||
{ Timestamp = System.DateTime.UtcNow
|
{ Timestamp = System.DateTime.UtcNow
|
||||||
Cooldown = defaultShield.Cooldown
|
Cooldown = defaultShield.Cooldown
|
||||||
Type = Shielding defaultShield.Id }
|
Type = Shielding defaultShield.Id }
|
||||||
|]
|
]
|
||||||
|
|
||||||
let sendInitialEmbed (client : DiscordClient) =
|
let sendInitialEmbed (client : DiscordClient) =
|
||||||
async {
|
async {
|
||||||
@ -173,7 +173,7 @@ let handleArsenal (ctx : IDiscordContext) =
|
|||||||
let updatedPlayer =
|
let updatedPlayer =
|
||||||
if not hasStockWeapons then {
|
if not hasStockWeapons then {
|
||||||
Player.removeExpiredActions player with
|
Player.removeExpiredActions player with
|
||||||
Events = TrainerEvents |> Array.append player.Events
|
Events = TrainerEvents @ player.Events
|
||||||
Inventory = Inventory.hackToItem defaultHack::Inventory.shieldToItem defaultShield::player.Inventory
|
Inventory = Inventory.hackToItem defaultHack::Inventory.shieldToItem defaultShield::player.Inventory
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -21,7 +21,11 @@ let tokenStore = getVar "TOKEN_STORE"
|
|||||||
let channelEventsHackerBattle = getId "CHANNEL_EVENTS_HACKER_BATTLE"
|
let channelEventsHackerBattle = getId "CHANNEL_EVENTS_HACKER_BATTLE"
|
||||||
let channelTraining = getId "CHANNEL_TRAINING"
|
let channelTraining = getId "CHANNEL_TRAINING"
|
||||||
let channelArmory = getId "CHANNEL_ARMORY"
|
let channelArmory = getId "CHANNEL_ARMORY"
|
||||||
|
let channelBackAlley = getId "CHANNEL_BACKALLEY"
|
||||||
let channelBattle = getId "CHANNEL_BATTLE"
|
let channelBattle = getId "CHANNEL_BATTLE"
|
||||||
|
let channelMarket = getId "CHANNEL_MARKET"
|
||||||
|
let channelAccessoryShop = getId "CHANNEL_ACCESSORIES"
|
||||||
|
|
||||||
//let channelThievery = getId "CHANNEL_THIEVERY"
|
//let channelThievery = getId "CHANNEL_THIEVERY"
|
||||||
let botIdHackerBattle = getId "BOT_HACKER_BATTLE"
|
let botIdHackerBattle = getId "BOT_HACKER_BATTLE"
|
||||||
let botIdArmory = getId "BOT_ARMORY"
|
let botIdArmory = getId "BOT_ARMORY"
|
||||||
|
100
Bot/Items.json
100
Bot/Items.json
@ -73,5 +73,105 @@
|
|||||||
380
|
380
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 12,
|
||||||
|
"Name": "Protein Powder",
|
||||||
|
"Price": 50,
|
||||||
|
"Type": {
|
||||||
|
"Case": "Food",
|
||||||
|
"Fields": [
|
||||||
|
0,
|
||||||
|
30
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 13,
|
||||||
|
"Name": "Toro Loco",
|
||||||
|
"Price": 50,
|
||||||
|
"Type": {
|
||||||
|
"Case": "Food",
|
||||||
|
"Fields": [
|
||||||
|
1,
|
||||||
|
30
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 14,
|
||||||
|
"Name": "Cigarettes",
|
||||||
|
"Price": 50,
|
||||||
|
"Type": {
|
||||||
|
"Case": "Food",
|
||||||
|
"Fields": [
|
||||||
|
2,
|
||||||
|
30
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 15,
|
||||||
|
"Name": "Moon Pie",
|
||||||
|
"Price": 50,
|
||||||
|
"Type": {
|
||||||
|
"Case": "Food",
|
||||||
|
"Fields": [
|
||||||
|
3,
|
||||||
|
30
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 20,
|
||||||
|
"Name": "Kettle Bell",
|
||||||
|
"Price": 250,
|
||||||
|
"Type": {
|
||||||
|
"Case": "Accessory",
|
||||||
|
"Fields": [
|
||||||
|
0,
|
||||||
|
25,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 21,
|
||||||
|
"Name": "Headphones",
|
||||||
|
"Price": 250,
|
||||||
|
"Type": {
|
||||||
|
"Case": "Accessory",
|
||||||
|
"Fields": [
|
||||||
|
1,
|
||||||
|
25,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 22,
|
||||||
|
"Name": "Silk Shirt",
|
||||||
|
"Price": 250,
|
||||||
|
"Type": {
|
||||||
|
"Case": "Accessory",
|
||||||
|
"Fields": [
|
||||||
|
2,
|
||||||
|
0,
|
||||||
|
25
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 23,
|
||||||
|
"Name": "Buddha Keychain",
|
||||||
|
"Price": 250,
|
||||||
|
"Type": {
|
||||||
|
"Case": "Accessory",
|
||||||
|
"Fields": [
|
||||||
|
3,
|
||||||
|
0,
|
||||||
|
25
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user