Merge branch 'arthur_classes'

pull/4/head
arthur.valin 2 years ago
commit c9ae9a5e4b

@ -0,0 +1,52 @@
<CascadingValue Value="@this">
<div class="container">
<div class="row">
<div class="col-6">
<div>Available items:</div>
<div>
<div class="css-grid">
<CascadingValue Value="@this">
@foreach (var item in Items)
{
<CraftingItem Item="item" NoDrop="true"/>
}
</CascadingValue>
</div>
</div>
</div>
<div class="col-6">
<div>Recipe</div>
<div>
<div class="css-recipe">
<CraftingItem Index="0"/>
<CraftingItem Index="1"/>
<CraftingItem Index="2"/>
<CraftingItem Index="3"/>
<CraftingItem Index="4"/>
<CraftingItem Index="5"/>
<CraftingItem Index="6"/>
<CraftingItem Index="7"/>
<CraftingItem Index="8"/>
</div>
</div>
<div>Result</div>
<div>
<CraftingItem Item="RecipeResult"/>
</div>
</div>
<div class="col-12">
<div>Actions</div>
<div class="actions" id="actions">
</div>
</div>
</div>
</div>
</CascadingValue>

@ -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<CraftingAction>();
Actions.CollectionChanged += OnActionsCollectionChanged;
this.RecipeItems = new List<Item> { null, null, null, null, null, null, null, null, null };
}
public ObservableCollection<CraftingAction> Actions { get; set; }
public Item CurrentDragItem { get; set; }
[Parameter]
public List<Item> Items { get; set; }
public List<Item> RecipeItems { get; set; }
public Item RecipeResult
{
get => this._recipeResult;
set
{
if (this._recipeResult == value)
{
return;
}
this._recipeResult = value;
this.StateHasChanged();
}
}
[Parameter]
public List<CraftingRecipe> Recipes { get; set; }
/// <summary>
/// Gets or sets the java script runtime.
/// </summary>
[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);
}
}
}

@ -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;
}

@ -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);
});
}
}

@ -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; }
}
}

@ -0,0 +1,16 @@
@using CraftSharp.Models
<div
class="item"
ondragover="event.preventDefault();"
draggable="true"
@ondragstart="@OnDragStart"
@ondrop="@OnDrop"
@ondragenter="@OnDragEnter"
@ondragleave="@OnDragLeave">
@if (Item != null)
{
@Item.DisplayName
}
</div>

@ -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 });
}
}
}

@ -0,0 +1,6 @@
.item {
width: 64px;
height: 64px;
border: 1px solid;
overflow: hidden;
}

@ -0,0 +1,11 @@
using CraftSharp.Models;
namespace CraftSharp.Components
{
public class CraftingRecipe
{
public Item Give { get; set; }
public List<List<string>> Have { get; set; }
}
}

@ -0,0 +1,11 @@
@typeparam TItem
<div>
@if ((Items?.Count ?? 0) != 0)
{
@foreach (var item in Items)
{
@ShowTemplate(item);
}
}
</div>

@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Components;
namespace CraftSharp.Components
{
public partial class ShowItems<TItem>
{
[Parameter]
public List<TItem> Items { get; set; }
[Parameter]
public RenderFragment<TItem> ShowTemplate { get; set; }
}
}

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>41eb41f8-57fb-408a-baab-7328f468e749</UserSecretsId>
<DockerDefaultTargetOS>Windows</DockerDefaultTargetOS>
<DockerfileContext>.</DockerfileContext>
</PropertyGroup>
<ItemGroup>
<Content Include="Models\Armor.cs" />
<Content Include="Models\Block.cs" />
<Content Include="Models\Boots.cs" />
<Content Include="Models\Chestplate.cs" />
<Content Include="Models\Helmet.cs" />
<Content Include="Models\Item.cs" />
<Content Include="Models\Leggings.cs" />
<Content Include="Models\Rarities.cs" />
<Content Include="Models\Tool.cs" />
<Content Include="Models\Trade.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
</ItemGroup>
</Project>

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>41eb41f8-57fb-408a-baab-7328f468e749</UserSecretsId>
<DockerDefaultTargetOS>Windows</DockerDefaultTargetOS>
<DockerfileContext>.</DockerfileContext>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\Images\CraftSharp-Logo.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

@ -1,3 +1,4 @@
<<<<<<< HEAD
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
@ -29,3 +30,44 @@
</ItemGroup>
</Project>
=======
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>41eb41f8-57fb-408a-baab-7328f468e749</UserSecretsId>
<DockerDefaultTargetOS>Windows</DockerDefaultTargetOS>
<DockerfileContext>.</DockerfileContext>
</PropertyGroup>
<ItemGroup>
<Content Include="Models\Item.cs" />
<Content Include="Models\ItemModel.cs" />
<Content Include="Models\Rarities.cs" />
<Content Include="Models\Trade.cs" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Shared\HeaderLayout.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="Shared\CraftLayout.css" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.17.0" />
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\Images\CraftSharp-Logo.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
>>>>>>> arthur_classes

@ -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;
}
}
}

@ -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<string> EnchantCategories { get; set; }
public List<string> RepairWith { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime? UpdatedDate { get; set; }
public string ImageBase64 { get; set; }
public Rarities Rarity { get; set; }
}
}

@ -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<string> EnchantCategories { get; set; }
public List<string> 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; }
}
}

@ -0,0 +1,10 @@
namespace CraftSharp.Models
{
public enum Rarities
{
Common,
Rare,
Epic,
Legendary
}
}

@ -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; }
}
}

@ -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<Index> Localizer { get; set; }
}
}

@ -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<IDataService, DataApiService>();
// Configure the localtization
builder.Services.Configure<RequestLocalizationOptions>(options =>
{

@ -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<int> Count()
{
return await _http.GetFromJsonAsync<int>("https://localhost:7234/api/Crafting/count");
}
public async Task<List<Item>> List(int currentPage, int pageSize)
{
return await _http.GetFromJsonAsync<List<Item>>($"https://localhost:7234/api/Crafting/?currentPage={currentPage}&pageSize={pageSize}");
}
public async Task<Item> GetById(int id)
{
return await _http.GetFromJsonAsync<Item>($"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<List<CraftingRecipe>> GetRecipes()
{
return await _http.GetFromJsonAsync<List<CraftingRecipe>>("https://localhost:7234/api/Crafting/recipe");
}
}
}

@ -0,0 +1,21 @@
using CraftSharp.Components;
using CraftSharp.Models;
namespace CraftSharp.Services
{
public interface IDataService
{
Task Add(ItemModel model);
Task<int> Count();
Task<List<Item>> List(int currentPage, int pageSize);
Task<Item> GetById(int id);
Task Update(int id, ItemModel model);
Task Delete(int id);
Task<List<CraftingRecipe>> GetRecipes();
}
}

@ -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
}
]
}
Loading…
Cancel
Save