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"
|
||||
WHERE discord_id = @did
|
||||
"""
|
||||
|> Sql.executeAsync (fun read -> {
|
||||
|> Sql.executeAsync (fun read ->
|
||||
let inv = read.intArray "inventory"
|
||||
{
|
||||
DiscordId = read.string "discord_id" |> uint64
|
||||
Name = read.string "display_name"
|
||||
Bank = read.int "gbt" * 1<GBT>
|
||||
Inventory = read.intArray "inventory" |> Array.toList
|
||||
Inventory = inv |> Array.toList
|
||||
Strength = read.int "strength"
|
||||
Focus = read.int "focus"
|
||||
Charisma = read.int "charm"
|
||||
Charisma = read.int "charisma"
|
||||
Luck = read.int "luck"
|
||||
})
|
||||
|> Async.AwaitTask
|
||||
|
@ -33,7 +33,7 @@ let constructButtons (actionId: string) (buttonInfo : string) (player: PlayerDat
|
||||
|> List.map (fun item ->
|
||||
let action =
|
||||
player.Events
|
||||
|> Array.tryFind (fun i ->
|
||||
|> List.tryFind (fun i ->
|
||||
match i.Type with
|
||||
| Hacking h -> h.HackId = item.Id && h.IsInstigator
|
||||
| Shielding id -> id = item.Id
|
||||
@ -101,7 +101,7 @@ let responseSuccessfulHack earnedMoney (targetId : uint64) amountTaken (hack : H
|
||||
let responseCreatedShield (shield : ShieldItem) =
|
||||
let embed = DiscordEmbedBuilder().WithImageUrl(getItemGif shield.Id)
|
||||
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()
|
||||
.AddEmbed(embed)
|
||||
|
@ -21,7 +21,6 @@ module Inventory =
|
||||
Class = hackClass
|
||||
Cooldown = cooldown
|
||||
}
|
||||
|
||||
let itemToShield item hackClass cooldown = {
|
||||
Id = item.Id
|
||||
Name = item.Name
|
||||
@ -29,31 +28,48 @@ module Inventory =
|
||||
Class = hackClass
|
||||
Cooldown = cooldown
|
||||
}
|
||||
let itemToFood item targetStat boostAmount = {
|
||||
Id = item.Id
|
||||
Name = item.Name
|
||||
Price = item.Price
|
||||
TargetStat = targetStat
|
||||
BoostAmount = boostAmount
|
||||
}
|
||||
let hackToItem (hack : HackItem) = {
|
||||
Id = hack.Id
|
||||
Name = hack.Name
|
||||
Price = hack.Price
|
||||
Type = Hack (hack.Power, hack.Class, hack.Cooldown)
|
||||
Details = Hack (hack.Power, hack.Class, hack.Cooldown)
|
||||
}
|
||||
let shieldToItem (shield : ShieldItem) = {
|
||||
Id = shield.Id
|
||||
Name = shield.Name
|
||||
Price = shield.Price
|
||||
Type = Shield (shield.Class, shield.Cooldown)
|
||||
Details = Shield (shield.Class, shield.Cooldown)
|
||||
}
|
||||
|
||||
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 =
|
||||
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 =
|
||||
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)
|
||||
let getShieldItems 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)
|
||||
let findItemById id inventory = inventory |> List.find (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)
|
||||
let findShieldById id inventory =
|
||||
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 =
|
||||
inventory |> getHackItems |> List.tryFind (fun item -> item.Id = id)
|
||||
let tryFindShieldById id inventory =
|
||||
@ -70,14 +88,14 @@ module WeaponClass =
|
||||
let SameTargetAttackCooldown = System.TimeSpan.FromHours(1)
|
||||
|
||||
let getClassButtonColor item =
|
||||
match item.Type with
|
||||
match item.Details with
|
||||
| Hack (_,0,_) | Shield (0,_) -> ButtonStyle.Danger
|
||||
| Hack (_,1,_) | Shield (1,_) -> ButtonStyle.Primary
|
||||
| Hack (_,2,_) | Shield (2,_) -> ButtonStyle.Success
|
||||
| _ -> ButtonStyle.Primary
|
||||
|
||||
let getClassEmbedColor item =
|
||||
match item.Type with
|
||||
match item.Details with
|
||||
| Hack (_,0,_) | Shield (0,_) -> DiscordColor.Red
|
||||
| Hack (_,1,_) | Shield (1,_) -> DiscordColor.Blurple
|
||||
| Hack (_,2,_) | Shield (2,_) -> DiscordColor.Green
|
||||
@ -120,8 +138,8 @@ module PlayerStats =
|
||||
// let hoursElapsed = (DateTime.UtcNow - lastRead).Hours
|
||||
// let totalDecay = float hoursElapsed * statConfig.BaseDecayRate
|
||||
let modMinMax =
|
||||
let min = items |> List.sumBy (fun item -> match item.Type with | Accessory(_,floorBoost,_) -> floorBoost | _ -> 0)
|
||||
let max = items |> List.sumBy (fun item -> match item.Type with | Accessory(_,_,ceilBoost) -> ceilBoost | _ -> 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.Details with | Accessory(_,_,ceilBoost) -> ceilBoost | _ -> 0)
|
||||
Range.create (statConfig.BaseRange.Min + min) (statConfig.BaseRange.Max + max)
|
||||
let amountAfterDecay = modMinMax |> Range.constrain amount
|
||||
{ Id = statId ; Amount = amountAfterDecay ; ModRange = modMinMax ; LastRead = DateTime.UtcNow }
|
||||
|
@ -24,12 +24,16 @@ type ItemId =
|
||||
| Firewall = 6
|
||||
| Encryption = 7
|
||||
| Cypher = 8
|
||||
| ProteinPowder = 12
|
||||
| ToroLoco = 13
|
||||
| Cigs = 14
|
||||
| MoonPie = 15
|
||||
|
||||
type StatId =
|
||||
| Strength = 0
|
||||
| Focus = 1
|
||||
| Luck = 2
|
||||
| Charisma = 3
|
||||
| Charisma = 2
|
||||
| Luck = 3
|
||||
|
||||
type StatConfig = {
|
||||
Id : StatId
|
||||
@ -112,7 +116,14 @@ type AccessoryItem = {
|
||||
CeilBoost : int
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type ItemType =
|
||||
| Hack
|
||||
| Shield
|
||||
| Food
|
||||
| Accessory
|
||||
|
||||
type ItemDetails =
|
||||
| Hack of power : int * hackClass : int * cooldown : int<mins>
|
||||
| Shield of shieldClass : int * cooldown : int<mins>
|
||||
| Food of targetStat : StatId * boostAmount : int
|
||||
@ -121,7 +132,8 @@ and Item = {
|
||||
Id : int
|
||||
Name : string
|
||||
Price : int<GBT>
|
||||
Type : ItemType
|
||||
// Type : ItemType
|
||||
Details : ItemDetails
|
||||
}
|
||||
and Inventory = Item list
|
||||
and PlayerData = {
|
||||
|
@ -19,7 +19,7 @@ let checkAlreadyHackedTarget defender attacker =
|
||||
defender
|
||||
|> Player.removeExpiredActions
|
||||
|> fun d -> d.Events
|
||||
|> Array.tryFind (fun event ->
|
||||
|> List.tryFind (fun event ->
|
||||
match event.Type with
|
||||
| Hacking h -> h.Adversary.Id = attacker.DiscordId && h.IsInstigator = false
|
||||
| _ -> false)
|
||||
@ -32,7 +32,7 @@ let checkAlreadyHackedTarget defender attacker =
|
||||
|
||||
let checkWeaponHasCooldown (weapon : Item) attacker =
|
||||
attacker.Events
|
||||
|> Array.tryFind (fun a ->
|
||||
|> List.tryFind (fun a ->
|
||||
match a.Type with
|
||||
| Hacking h -> h.HackId = weapon.Id && h.IsInstigator
|
||||
| Shielding id -> id = weapon.Id
|
||||
@ -56,9 +56,9 @@ let checkPlayerOwnsWeapon (item : Item) player =
|
||||
let checkPlayerHasShieldSlotsAvailable player =
|
||||
let updatedPlayer = player |> Player.removeExpiredActions
|
||||
let defenses = Player.getShieldEvents updatedPlayer
|
||||
match defenses |> Array.length >= 3 with
|
||||
match defenses |> List.length >= 3 with
|
||||
| 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
|
||||
Error $"You are only allowed three shields at a time. Wait {cooldown} to add another shield"
|
||||
| false -> Ok updatedPlayer
|
||||
@ -72,16 +72,16 @@ let runHackerBattle defender (hack : HackItem) =
|
||||
defender
|
||||
|> Player.removeExpiredActions
|
||||
|> fun p -> p.Events
|
||||
|> Array.choose (fun event ->
|
||||
|> List.choose (fun event ->
|
||||
match event.Type with
|
||||
| Shielding id -> defender.Inventory |> Inventory.getShieldItems |> List.find (fun item -> item.Id = id) |> Some
|
||||
| _ -> None)
|
||||
|> Array.map (fun shield -> if hack.Class = shield.Class then Weak else Strong)
|
||||
|> Array.contains Weak
|
||||
|> List.map (fun shield -> if hack.Class = shield.Class then Weak else Strong)
|
||||
|> List.contains Weak
|
||||
|
||||
let updateCombatants successfulHack (attacker : PlayerData) (defender : PlayerData) (hack : HackItem) prize =
|
||||
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 hackEvent = {
|
||||
HackId = hack.Id
|
||||
|
@ -15,7 +15,7 @@ let getBuyItemsEmbed (playerInventory : Inventory) (storeInventory : Inventory)
|
||||
storeInventory
|
||||
|> List.map (fun item ->
|
||||
let embed = DiscordEmbedBuilder()
|
||||
match item.Type with
|
||||
match item.Details with
|
||||
| Hack(power,_,cooldown) ->
|
||||
embed.AddField($"$GBT Reward |", string power, 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)
|
||||
.WithThumbnail(Embeds.getItemIcon item.Id)
|
||||
|> 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
|
||||
.AddField("Price 💰", (if item.Price = 0<GBT> then "Free" else $"{item.Price} $GBT"), true)
|
||||
.WithColor(WeaponClass.getClassEmbedColor item)
|
||||
@ -62,6 +70,26 @@ let getSellEmbed (items : Item list) =
|
||||
.AddComponents(buttons)
|
||||
.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 =
|
||||
if player.Bank - item.Price >= 0<GBT>
|
||||
then Ok player
|
||||
@ -127,12 +155,24 @@ let handleSell (ctx : IDiscordContext) itemId =
|
||||
do!
|
||||
[ DbService.updatePlayer updatedPlayer |> 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.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 ctx = DiscordEventContext event :> IDiscordContext
|
||||
let id = ctx.GetInteractionId()
|
||||
@ -160,15 +200,38 @@ type Store() =
|
||||
do! Messaging.sendSimpleResponse ctx msg
|
||||
}
|
||||
|
||||
[<SlashCommand("buy-hack", "Purchase a hack attack you can use to earn GoodBoyTokenz")>]
|
||||
member _.BuyHack (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (buy Inventory.filterByHacks)
|
||||
let checkChannel (ctx : IDiscordContext) =
|
||||
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")>]
|
||||
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")>]
|
||||
member this.SellHack (ctx : InteractionContext) = enforceChannel (DiscordInteractionContext(ctx)) (sell "Hacks" Inventory.filterByHacks)
|
||||
|
||||
[<SlashCommand("sell-shield", "Sell a shield for GoodBoyTokenz")>]
|
||||
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
|
||||
|> Player.removeExpiredActions
|
||||
|> fun p -> p.Events
|
||||
|> Array.tryFind (fun e ->
|
||||
|> List.tryFind (fun e ->
|
||||
match e.Type with Stealing _ -> true | _ -> false)
|
||||
|> function
|
||||
| Some act ->
|
||||
@ -95,7 +95,7 @@ let checkThiefCooldown attacker =
|
||||
attacker
|
||||
|> Player.removeExpiredActions
|
||||
|> 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
|
||||
| Some act ->
|
||||
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 defaultShield = Armory.weapons |> Inventory.findShieldById (int ItemId.Firewall)
|
||||
|
||||
let TrainerEvents = [|
|
||||
let TrainerEvents = [
|
||||
{ Timestamp = System.DateTime.UtcNow
|
||||
Cooldown = defaultHack.Cooldown
|
||||
Type = Hacking {
|
||||
@ -23,7 +23,7 @@ let TrainerEvents = [|
|
||||
{ Timestamp = System.DateTime.UtcNow
|
||||
Cooldown = defaultShield.Cooldown
|
||||
Type = Shielding defaultShield.Id }
|
||||
|]
|
||||
]
|
||||
|
||||
let sendInitialEmbed (client : DiscordClient) =
|
||||
async {
|
||||
@ -173,7 +173,7 @@ let handleArsenal (ctx : IDiscordContext) =
|
||||
let updatedPlayer =
|
||||
if not hasStockWeapons then {
|
||||
Player.removeExpiredActions player with
|
||||
Events = TrainerEvents |> Array.append player.Events
|
||||
Events = TrainerEvents @ player.Events
|
||||
Inventory = Inventory.hackToItem defaultHack::Inventory.shieldToItem defaultShield::player.Inventory
|
||||
}
|
||||
else
|
||||
|
@ -21,7 +21,11 @@ let tokenStore = getVar "TOKEN_STORE"
|
||||
let channelEventsHackerBattle = getId "CHANNEL_EVENTS_HACKER_BATTLE"
|
||||
let channelTraining = getId "CHANNEL_TRAINING"
|
||||
let channelArmory = getId "CHANNEL_ARMORY"
|
||||
let channelBackAlley = getId "CHANNEL_BACKALLEY"
|
||||
let channelBattle = getId "CHANNEL_BATTLE"
|
||||
let channelMarket = getId "CHANNEL_MARKET"
|
||||
let channelAccessoryShop = getId "CHANNEL_ACCESSORIES"
|
||||
|
||||
//let channelThievery = getId "CHANNEL_THIEVERY"
|
||||
let botIdHackerBattle = getId "BOT_HACKER_BATTLE"
|
||||
let botIdArmory = getId "BOT_ARMORY"
|
||||
|
100
Bot/Items.json
100
Bot/Items.json
@ -73,5 +73,105 @@
|
||||
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