diff --git a/src/CraftSharp/Components/Crafting.razor b/src/CraftSharp/Components/Crafting.razor new file mode 100644 index 0000000..378f220 --- /dev/null +++ b/src/CraftSharp/Components/Crafting.razor @@ -0,0 +1,52 @@ + + + + + + Available items: + + + + @foreach (var item in Items) + { + + } + + + + + + + + Recipe + + + + + + + + + + + + + + + + + Result + + + + + + + Actions + + + + + + + \ No newline at end of file diff --git a/src/CraftSharp/Components/Crafting.razor.cs b/src/CraftSharp/Components/Crafting.razor.cs new file mode 100644 index 0000000..3fc4f9a --- /dev/null +++ b/src/CraftSharp/Components/Crafting.razor.cs @@ -0,0 +1,83 @@ +using CraftSharp.Models; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; +using System.Collections.ObjectModel; +using System.Collections.Specialized; + +namespace CraftSharp.Components +{ + public partial class Crafting + { + private Item _recipeResult; + + [CascadingParameter] + public Crafting Parent { get; set; } + + public Crafting() + { + Actions = new ObservableCollection(); + Actions.CollectionChanged += OnActionsCollectionChanged; + this.RecipeItems = new List { null, null, null, null, null, null, null, null, null }; + } + + public ObservableCollection Actions { get; set; } + public Item CurrentDragItem { get; set; } + + [Parameter] + public List Items { get; set; } + + public List RecipeItems { get; set; } + + public Item RecipeResult + { + get => this._recipeResult; + set + { + if (this._recipeResult == value) + { + return; + } + + this._recipeResult = value; + this.StateHasChanged(); + } + } + + [Parameter] + public List Recipes { get; set; } + + /// + /// Gets or sets the java script runtime. + /// + [Inject] + internal IJSRuntime JavaScriptRuntime { get; set; } + + public void CheckRecipe() + { + RecipeResult = null; + + // Get the current model + var currentModel = string.Join("|", this.RecipeItems.Select(s => s != null ? s.Name : string.Empty)); + + this.Actions.Add(new CraftingAction { Action = $"Items : {currentModel}" }); + + foreach (var craftingRecipe in Recipes) + { + // Get the recipe model + var recipeModel = string.Join("|", craftingRecipe.Have.SelectMany(s => s)); + + this.Actions.Add(new CraftingAction { Action = $"Recipe model : {recipeModel}" }); + + if (currentModel == recipeModel) + { + RecipeResult = craftingRecipe.Give; + } + } + } + + private void OnActionsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) + { + JavaScriptRuntime.InvokeVoidAsync("Crafting.AddActions", e.NewItems); + } + } +} diff --git a/src/CraftSharp/Components/Crafting.razor.css b/src/CraftSharp/Components/Crafting.razor.css new file mode 100644 index 0000000..1c0cb8b --- /dev/null +++ b/src/CraftSharp/Components/Crafting.razor.css @@ -0,0 +1,19 @@ +.css-grid { + grid-template-columns: repeat(4,minmax(0,1fr)); + gap: 10px; + display: grid; + width: 286px; +} + +.css-recipe { + grid-template-columns: repeat(3,minmax(0,1fr)); + gap: 10px; + display: grid; + width: 212px; +} + +.actions { + border: 1px solid black; + height: 250px; + overflow: scroll; +} diff --git a/src/CraftSharp/Components/Crafting.razor.js b/src/CraftSharp/Components/Crafting.razor.js new file mode 100644 index 0000000..3fcb76d --- /dev/null +++ b/src/CraftSharp/Components/Crafting.razor.js @@ -0,0 +1,16 @@ +window.Crafting = +{ + AddActions: function (data) { + + data.forEach(element => { + var div = document.createElement('div'); + div.innerHTML = 'Action: ' + element.action + ' - Index: ' + element.index; + + if (element.item) { + div.innerHTML += ' - Item Name: ' + element.item.name; + } + + document.getElementById('actions').appendChild(div); + }); + } +} \ No newline at end of file diff --git a/src/CraftSharp/Components/CraftingAction.cs b/src/CraftSharp/Components/CraftingAction.cs new file mode 100644 index 0000000..fd7294a --- /dev/null +++ b/src/CraftSharp/Components/CraftingAction.cs @@ -0,0 +1,11 @@ +using CraftSharp.Models; + +namespace CraftSharp.Components +{ + public class CraftingAction + { + public string Action { get; set; } + public int Index { get; set; } + public Item Item { get; set; } + } +} diff --git a/src/CraftSharp/Components/CraftingItem.razor b/src/CraftSharp/Components/CraftingItem.razor new file mode 100644 index 0000000..450dfc5 --- /dev/null +++ b/src/CraftSharp/Components/CraftingItem.razor @@ -0,0 +1,16 @@ +@using CraftSharp.Models + + + + @if (Item != null) + { + @Item.DisplayName + } + \ No newline at end of file diff --git a/src/CraftSharp/Components/CraftingItem.razor.cs b/src/CraftSharp/Components/CraftingItem.razor.cs new file mode 100644 index 0000000..9668a0a --- /dev/null +++ b/src/CraftSharp/Components/CraftingItem.razor.cs @@ -0,0 +1,66 @@ +using CraftSharp.Components; +using CraftSharp.Models; +using Microsoft.AspNetCore.Components; + +namespace CraftSharp.Components +{ + public partial class CraftingItem + { + [Parameter] + public int Index { get; set; } + + [Parameter] + public Item Item { get; set; } + + [Parameter] + public bool NoDrop { get; set; } + + [CascadingParameter] + public Crafting Parent { get; set; } + + internal void OnDragEnter() + { + if (NoDrop) + { + return; + } + + Parent.Actions.Add(new CraftingAction { Action = "Drag Enter", Item = this.Item, Index = this.Index }); + } + + internal void OnDragLeave() + { + if (NoDrop) + { + return; + } + + Parent.Actions.Add(new CraftingAction { Action = "Drag Leave", Item = this.Item, Index = this.Index }); + } + + internal void OnDrop() + { + if (NoDrop) + { + return; + } + + this.Item = Parent.CurrentDragItem; + Parent.RecipeItems[this.Index] = this.Item; + + Parent.Actions.Add(new CraftingAction { Action = "Drop", Item = this.Item, Index = this.Index }); + + // Check recipe + Parent.CheckRecipe(); + } + + private void OnDragStart() + { + Parent.CurrentDragItem = this.Item; + + Parent.Actions.Add(new CraftingAction { Action = "Drag Start", Item = this.Item, Index = this.Index }); + } + + + } +} diff --git a/src/CraftSharp/Components/CraftingItem.razor.css b/src/CraftSharp/Components/CraftingItem.razor.css new file mode 100644 index 0000000..d6f5ec3 --- /dev/null +++ b/src/CraftSharp/Components/CraftingItem.razor.css @@ -0,0 +1,6 @@ +.item { + width: 64px; + height: 64px; + border: 1px solid; + overflow: hidden; +} diff --git a/src/CraftSharp/Components/CraftingRecipe.cs b/src/CraftSharp/Components/CraftingRecipe.cs new file mode 100644 index 0000000..578b68d --- /dev/null +++ b/src/CraftSharp/Components/CraftingRecipe.cs @@ -0,0 +1,11 @@ +using CraftSharp.Models; + +namespace CraftSharp.Components +{ + public class CraftingRecipe + { + public Item Give { get; set; } + public List> Have { get; set; } + } + +} diff --git a/src/CraftSharp/Components/ShowItems.razor b/src/CraftSharp/Components/ShowItems.razor new file mode 100644 index 0000000..62d31ba --- /dev/null +++ b/src/CraftSharp/Components/ShowItems.razor @@ -0,0 +1,11 @@ +@typeparam TItem + + + @if ((Items?.Count ?? 0) != 0) + { + @foreach (var item in Items) + { + @ShowTemplate(item); + } + } + \ No newline at end of file diff --git a/src/CraftSharp/Components/ShowItems.razor.cs b/src/CraftSharp/Components/ShowItems.razor.cs new file mode 100644 index 0000000..5ac9e39 --- /dev/null +++ b/src/CraftSharp/Components/ShowItems.razor.cs @@ -0,0 +1,13 @@ +using Microsoft.AspNetCore.Components; + +namespace CraftSharp.Components +{ + public partial class ShowItems + { + [Parameter] + public List Items { get; set; } + + [Parameter] + public RenderFragment ShowTemplate { get; set; } + } +} diff --git a/src/CraftSharp/CraftSharp - Backup (1).csproj b/src/CraftSharp/CraftSharp - Backup (1).csproj new file mode 100644 index 0000000..6fa0141 --- /dev/null +++ b/src/CraftSharp/CraftSharp - Backup (1).csproj @@ -0,0 +1,30 @@ + + + + net6.0 + enable + enable + 41eb41f8-57fb-408a-baab-7328f468e749 + Windows + . + + + + + + + + + + + + + + + + + + + + + diff --git a/src/CraftSharp/CraftSharp - Backup.csproj b/src/CraftSharp/CraftSharp - Backup.csproj new file mode 100644 index 0000000..44789d7 --- /dev/null +++ b/src/CraftSharp/CraftSharp - Backup.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + enable + 41eb41f8-57fb-408a-baab-7328f468e749 + Windows + . + + + + + + + + + + Always + + + + diff --git a/src/CraftSharp/CraftSharp.csproj b/src/CraftSharp/CraftSharp.csproj index a9a995b..b2a8b3c 100644 --- a/src/CraftSharp/CraftSharp.csproj +++ b/src/CraftSharp/CraftSharp.csproj @@ -1,3 +1,4 @@ +<<<<<<< HEAD @@ -29,3 +30,44 @@ +======= + + + + net6.0 + enable + enable + 41eb41f8-57fb-408a-baab-7328f468e749 + Windows + . + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + + + +>>>>>>> arthur_classes diff --git a/src/CraftSharp/Factories/ItemFactory.cs b/src/CraftSharp/Factories/ItemFactory.cs new file mode 100644 index 0000000..e0e91fd --- /dev/null +++ b/src/CraftSharp/Factories/ItemFactory.cs @@ -0,0 +1,55 @@ +using CraftSharp.Models; + +namespace CraftSharp.Factories +{ + public static class ItemFactory + { + public static ItemModel ToModel(Item item, byte[] imageContent) + { + return new ItemModel + { + Id = item.Id, + DisplayName = item.DisplayName, + Name = item.Name, + RepairWith = item.RepairWith, + EnchantCategories = item.EnchantCategories, + MaxDurability = item.MaxDurability, + StackSize = item.StackSize, + ImageContent = imageContent, + ImageBase64 = string.IsNullOrWhiteSpace(item.ImageBase64) ? Convert.ToBase64String(imageContent) : item.ImageBase64, + Rarity = item.Rarity + }; + } + + public static Item Create(ItemModel model) + { + return new Item + { + Id = model.Id, + DisplayName = model.DisplayName, + Name = model.Name, + RepairWith = model.RepairWith, + EnchantCategories = model.EnchantCategories, + MaxDurability = model.MaxDurability, + StackSize = model.StackSize, + CreatedDate = DateTime.Now, + ImageBase64 = Convert.ToBase64String(model.ImageContent), + Rarity = model.Rarity + }; + } + + public static void Update(Item item, ItemModel model) + { + item.DisplayName = model.DisplayName; + item.Name = model.Name; + item.RepairWith = model.RepairWith; + item.EnchantCategories = model.EnchantCategories; + item.MaxDurability = model.MaxDurability; + item.StackSize = model.StackSize; + item.UpdatedDate = DateTime.Now; + item.ImageBase64 = Convert.ToBase64String(model.ImageContent); + item.Rarity = model.Rarity; + + } +} +} diff --git a/src/CraftSharp/Models/Item.cs b/src/CraftSharp/Models/Item.cs new file mode 100644 index 0000000..eaf12d8 --- /dev/null +++ b/src/CraftSharp/Models/Item.cs @@ -0,0 +1,18 @@ +namespace CraftSharp.Models +{ + public class Item + { + public int Id { get; set; } + public string DisplayName { get; set; } + public string Name { get; set; } + public int StackSize { get; set; } + public int MaxDurability { get; set; } + public List EnchantCategories { get; set; } + public List RepairWith { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime? UpdatedDate { get; set; } + public string ImageBase64 { get; set; } + + public Rarities Rarity { get; set; } + } +} diff --git a/src/CraftSharp/Models/ItemModel.cs b/src/CraftSharp/Models/ItemModel.cs new file mode 100644 index 0000000..a778e4a --- /dev/null +++ b/src/CraftSharp/Models/ItemModel.cs @@ -0,0 +1,42 @@ +using System.ComponentModel.DataAnnotations; + + +namespace CraftSharp.Models +{ + public class ItemModel + { + public int Id { get; set; } + [Required] + [StringLength(50, ErrorMessage = "Le nom affiché ne doit pas dépasser 50 caractères.")] + public string DisplayName { get; set; } + + [Required] + [StringLength(50, ErrorMessage = "Le nom ne doit pas dépasser 50 caractères.")] + [RegularExpression(@"^[a-z''-'\s]{1,40}$", ErrorMessage = "Seulement les caractères en minuscule sont acceptées.")] + public string Name { get; set; } + + [Required] + [Range(1, 64)] + public int StackSize { get; set; } + + [Required] + [Range(1, 125)] + public int MaxDurability { get; set; } + + public List EnchantCategories { get; set; } + + public List RepairWith { get; set; } + + [Required] + [Range(typeof(bool), "true", "true", ErrorMessage = "Vous devez accepter les conditions.")] + public bool AcceptCondition { get; set; } + + [Required(ErrorMessage = "L'image de l'item est obligatoire !")] + public byte[] ImageContent { get; set; } + + public string ImageBase64 { get; set; } + + [Required] + public Rarities Rarity { get; set; } + } +} diff --git a/src/CraftSharp/Models/Rarities.cs b/src/CraftSharp/Models/Rarities.cs new file mode 100644 index 0000000..3fb17e1 --- /dev/null +++ b/src/CraftSharp/Models/Rarities.cs @@ -0,0 +1,10 @@ +namespace CraftSharp.Models +{ + public enum Rarities + { + Common, + Rare, + Epic, + Legendary + } +} diff --git a/src/CraftSharp/Models/Trade.cs b/src/CraftSharp/Models/Trade.cs new file mode 100644 index 0000000..6ca7cef --- /dev/null +++ b/src/CraftSharp/Models/Trade.cs @@ -0,0 +1,10 @@ +namespace CraftSharp.Models +{ + public class Trade + { + public Item GivenItem { get; set; } + public int GivenItemQuantity { get; set; } + public Item ReceivedItem { get; set; } + public int ReceivedItemQuantity { get; set; } + } +} diff --git a/src/CraftSharp/Pages/Index.razor.cs b/src/CraftSharp/Pages/Index.razor.cs index 4b50d5e..c350962 100644 --- a/src/CraftSharp/Pages/Index.razor.cs +++ b/src/CraftSharp/Pages/Index.razor.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Localization; +using CraftSharp.Models; namespace CraftSharp.Pages { @@ -7,5 +8,6 @@ namespace CraftSharp.Pages { [Inject] public IStringLocalizer Localizer { get; set; } + } } diff --git a/src/CraftSharp/Program.cs b/src/CraftSharp/Program.cs index 1390d26..5ced326 100644 --- a/src/CraftSharp/Program.cs +++ b/src/CraftSharp/Program.cs @@ -1,4 +1,5 @@ using CraftSharp.Data; +using CraftSharp.Services; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Localization; @@ -18,6 +19,10 @@ builder.Services.AddControllers(); // Add the localization to the app and specify the resources path builder.Services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; }); +builder.Services.AddHttpClient(); + +builder.Services.AddScoped(); + // Configure the localtization builder.Services.Configure(options => { diff --git a/src/CraftSharp/Services/DataApiService.cs b/src/CraftSharp/Services/DataApiService.cs new file mode 100644 index 0000000..0a8d477 --- /dev/null +++ b/src/CraftSharp/Services/DataApiService.cs @@ -0,0 +1,59 @@ +using CraftSharp.Components; +using CraftSharp.Factories; +using CraftSharp.Models; + +namespace CraftSharp.Services +{ + public class DataApiService : IDataService + { + private readonly HttpClient _http; + + public DataApiService( + HttpClient http) + { + _http = http; + } + + public async Task Add(ItemModel model) + { + // Get the item + var item = ItemFactory.Create(model); + + // Save the data + await _http.PostAsJsonAsync("https://localhost:7234/api/Crafting/", item); + } + + public async Task Count() + { + return await _http.GetFromJsonAsync("https://localhost:7234/api/Crafting/count"); + } + + public async Task> List(int currentPage, int pageSize) + { + return await _http.GetFromJsonAsync>($"https://localhost:7234/api/Crafting/?currentPage={currentPage}&pageSize={pageSize}"); + } + + public async Task GetById(int id) + { + return await _http.GetFromJsonAsync($"https://localhost:7234/api/Crafting/{id}"); + } + + public async Task Update(int id, ItemModel model) + { + // Get the item + var item = ItemFactory.Create(model); + + await _http.PutAsJsonAsync($"https://localhost:7234/api/Crafting/{id}", item); + } + + public async Task Delete(int id) + { + await _http.DeleteAsync($"https://localhost:7234/api/Crafting/{id}"); + } + + public async Task> GetRecipes() + { + return await _http.GetFromJsonAsync>("https://localhost:7234/api/Crafting/recipe"); + } + } +} diff --git a/src/CraftSharp/Services/IDataService.cs b/src/CraftSharp/Services/IDataService.cs new file mode 100644 index 0000000..c5a515c --- /dev/null +++ b/src/CraftSharp/Services/IDataService.cs @@ -0,0 +1,21 @@ +using CraftSharp.Components; +using CraftSharp.Models; + +namespace CraftSharp.Services +{ + public interface IDataService + { + Task Add(ItemModel model); + + Task Count(); + + Task> List(int currentPage, int pageSize); + Task GetById(int id); + + Task Update(int id, ItemModel model); + Task Delete(int id); + + Task> GetRecipes(); + } +} + diff --git a/src/CraftSharp/wwwroot/fake-data.json b/src/CraftSharp/wwwroot/fake-data.json new file mode 100644 index 0000000..30d311b --- /dev/null +++ b/src/CraftSharp/wwwroot/fake-data.json @@ -0,0 +1,469 @@ +{ + "blocks": [ + { + "id": 1, + "name": "Comveyer", + "stacksize": 35, + "rarity": "rare" + }, + { + "id": 2, + "name": "Uncorp", + "stacksize": 56, + "rarity": "legendary" + }, + { + "id": 3, + "name": "Oatfarm", + "stacksize": 27, + "rarity": "rare" + }, + { + "id": 4, + "name": "Isostream", + "stacksize": 21, + "rarity": "legendary" + }, + { + "id": 5, + "name": "Deepends", + "stacksize": 23, + "rarity": "rare" + }, + { + "id": 6, + "name": "Flumbo", + "stacksize": 26, + "rarity": "common" + }, + { + "id": 7, + "name": "Navir", + "stacksize": 64, + "rarity": "common" + }, + { + "id": 8, + "name": "Circum", + "stacksize": 31, + "rarity": "legendary" + }, + { + "id": 9, + "name": "Virva", + "stacksize": 30, + "rarity": "epic" + }, + { + "id": 10, + "name": "Zillanet", + "stacksize": 18, + "rarity": "common" + }, + { + "id": 11, + "name": "Ezent", + "stacksize": 49, + "rarity": "legendary" + }, + { + "id": 12, + "name": "Pigzart", + "stacksize": 48, + "rarity": "common" + }, + { + "id": 13, + "name": "Mantrix", + "stacksize": 6, + "rarity": "rare" + }, + { + "id": 14, + "name": "Aquamate", + "stacksize": 9, + "rarity": "rare" + }, + { + "id": 15, + "name": "Twiist", + "stacksize": 54, + "rarity": "legendary" + }, + { + "id": 16, + "name": "Mazuda", + "stacksize": 17, + "rarity": "rare" + }, + { + "id": 17, + "name": "Ecolight", + "stacksize": 50, + "rarity": "epic" + }, + { + "id": 18, + "name": "Greeker", + "stacksize": 40, + "rarity": "rare" + }, + { + "id": 19, + "name": "Stelaecor", + "stacksize": 28, + "rarity": "legendary" + }, + { + "id": 20, + "name": "Deviltoe", + "stacksize": 24, + "rarity": "epic" + }, + { + "id": 21, + "name": "Comveyor", + "stacksize": 39, + "rarity": "legendary" + }, + { + "id": 22, + "name": "Neptide", + "stacksize": 63, + "rarity": "common" + } + ], + "tools": [ + { + "id": 1, + "name": "Applideck", + "stacksize": 10, + "rarity": "common", + "damages": 3 + }, + { + "id": 2, + "name": "Kenegy", + "stacksize": 7, + "rarity": "legendary", + "damages": 7 + }, + { + "id": 3, + "name": "Pyramis", + "stacksize": 47, + "rarity": "epic", + "damages": 8 + }, + { + "id": 4, + "name": "Xsports", + "stacksize": 6, + "rarity": "rare", + "damages": 7 + }, + { + "id": 5, + "name": "Extragen", + "stacksize": 11, + "rarity": "common", + "damages": 10 + }, + { + "id": 6, + "name": "Recrisys", + "stacksize": 40, + "rarity": "rare", + "damages": 3 + }, + { + "id": 7, + "name": "Martgo", + "stacksize": 39, + "rarity": "legendary", + "damages": 6 + }, + { + "id": 8, + "name": "Lotron", + "stacksize": 11, + "rarity": "rare", + "damages": 9 + }, + { + "id": 9, + "name": "Flum", + "stacksize": 14, + "rarity": "common", + "damages": 4 + }, + { + "id": 10, + "name": "Terrago", + "stacksize": 23, + "rarity": "common", + "damages": 10 + }, + { + "id": 11, + "name": "Stralum", + "stacksize": 17, + "rarity": "common", + "damages": 9 + }, + { + "id": 12, + "name": "Unisure", + "stacksize": 4, + "rarity": "epic", + "damages": 2 + }, + { + "id": 13, + "name": "Xleen", + "stacksize": 6, + "rarity": "rare", + "damages": 1 + }, + { + "id": 14, + "name": "Knowlysis", + "stacksize": 4, + "rarity": "rare", + "damages": 7 + }, + { + "id": 15, + "name": "Exoteric", + "stacksize": 56, + "rarity": "epic", + "damages": 4 + }, + { + "id": 16, + "name": "Elentrix", + "stacksize": 43, + "rarity": "legendary", + "damages": 9 + }, + { + "id": 17, + "name": "Exostream", + "stacksize": 2, + "rarity": "common", + "damages": 10 + }, + { + "id": 18, + "name": "Helixo", + "stacksize": 50, + "rarity": "epic", + "damages": 1 + }, + { + "id": 19, + "name": "Eventage", + "stacksize": 31, + "rarity": "common", + "damages": 10 + }, + { + "id": 20, + "name": "Isosphere", + "stacksize": 44, + "rarity": "common", + "damages": 9 + }, + { + "id": 21, + "name": "Surelogic", + "stacksize": 18, + "rarity": "epic", + "damages": 3 + }, + { + "id": 22, + "name": "Accufarm", + "stacksize": 36, + "rarity": "common", + "damages": 6 + }, + { + "id": 23, + "name": "Recognia", + "stacksize": 13, + "rarity": "epic", + "damages": 4 + }, + { + "id": 24, + "name": "Fibrodyne", + "stacksize": 20, + "rarity": "rare", + "damages": 7 + }, + { + "id": 25, + "name": "Plasmosis", + "stacksize": 62, + "rarity": "common", + "damages": 2 + }, + { + "id": 26, + "name": "Dogtown", + "stacksize": 58, + "rarity": "common", + "damages": 6 + }, + { + "id": 27, + "name": "Edecine", + "stacksize": 56, + "rarity": "rare", + "damages": 3 + }, + { + "id": 28, + "name": "Spacewax", + "stacksize": 51, + "rarity": "legendary", + "damages": 8 + } + ], + "armors": [ + { + "id": 1, + "name": "Splinx", + "stacksize": 59, + "rarity": "common", + "toughness": 19 + }, + { + "id": 2, + "name": "Digigen", + "stacksize": 34, + "rarity": "legendary", + "toughness": 10 + }, + { + "id": 3, + "name": "Geoform", + "stacksize": 33, + "rarity": "legendary", + "toughness": 13 + }, + { + "id": 4, + "name": "Ovium", + "stacksize": 21, + "rarity": "legendary", + "toughness": 1 + }, + { + "id": 5, + "name": "Slambda", + "stacksize": 51, + "rarity": "common", + "toughness": 8 + }, + { + "id": 6, + "name": "Opticon", + "stacksize": 34, + "rarity": "rare", + "toughness": 18 + }, + { + "id": 7, + "name": "Combogen", + "stacksize": 22, + "rarity": "rare", + "toughness": 2 + }, + { + "id": 8, + "name": "Talae", + "stacksize": 38, + "rarity": "epic", + "toughness": 3 + }, + { + "id": 9, + "name": "Quotezart", + "stacksize": 63, + "rarity": "common", + "toughness": 7 + }, + { + "id": 10, + "name": "Edecine", + "stacksize": 54, + "rarity": "epic", + "toughness": 9 + }, + { + "id": 11, + "name": "Geekwagon", + "stacksize": 16, + "rarity": "common", + "toughness": 17 + }, + { + "id": 12, + "name": "Buzzmaker", + "stacksize": 1, + "rarity": "epic", + "toughness": 1 + }, + { + "id": 13, + "name": "Dreamia", + "stacksize": 11, + "rarity": "legendary", + "toughness": 3 + }, + { + "id": 14, + "name": "Memora", + "stacksize": 64, + "rarity": "legendary", + "toughness": 2 + }, + { + "id": 15, + "name": "Exerta", + "stacksize": 10, + "rarity": "legendary", + "toughness": 13 + }, + { + "id": 16, + "name": "Talkola", + "stacksize": 12, + "rarity": "rare", + "toughness": 10 + }, + { + "id": 17, + "name": "Zosis", + "stacksize": 12, + "rarity": "legendary", + "toughness": 2 + }, + { + "id": 18, + "name": "Aquazure", + "stacksize": 40, + "rarity": "rare", + "toughness": 6 + }, + { + "id": 19, + "name": "Crustatia", + "stacksize": 25, + "rarity": "common", + "toughness": 16 + } + ] +} \ No newline at end of file