private bool ConsumeInputAt(IPlayer byPlayer, ItemSlot[] inputSlots, int gridWidth, int colStart, int rowStart) { int gridHeight = inputSlots.Length / gridWidth; for (int col = 0; col < gridWidth; col++) { for (int row = 0; row < gridHeight; row++) { ItemSlot slot = GetElementInGrid(row, col, inputSlots, gridWidth); CraftingRecipeIngredient ingredient = GetElementInGrid(row - rowStart, col - colStart, resolvedIngredients, Width); if (ingredient == null) { continue; } if (slot.Itemstack == null) { return(false); } int quantity = ingredient.IsWildCard ? ingredient.Quantity : ingredient.ResolvedItemstack.StackSize; slot.Itemstack.Collectible.OnConsumedByCrafting(inputSlots, slot, this, ingredient, byPlayer, quantity); } } return(true); }
public bool MatchesAtPosition(int colStart, int rowStart, ItemSlot[] inputSlots, int gridWidth) { int gridHeight = inputSlots.Length / gridWidth; for (int col = 0; col < gridWidth; col++) { for (int row = 0; row < gridHeight; row++) { ItemStack inputStack = GetElementInGrid(row, col, inputSlots, gridWidth)?.Itemstack; CraftingRecipeIngredient ingredient = GetElementInGrid(row - rowStart, col - colStart, resolvedIngredients, Width); if ((inputStack == null) ^ (ingredient == null)) { return(false); } if (inputStack == null) { continue; } if (!ingredient.SatisfiesAsIngredient(inputStack)) { return(false); } if (!inputStack.Collectible.MatchesForCrafting(inputStack, this, ingredient)) { return(false); } } } return(true); }
/// <summary> /// Deserializes the recipe /// </summary> /// <param name="reader"></param> /// <param name="resolver"></param> public void FromBytes(BinaryReader reader, IWorldAccessor resolver) { Width = reader.ReadInt32(); Height = reader.ReadInt32(); Output = new CraftingRecipeIngredient(); Output.FromBytes(reader, resolver); Shapeless = reader.ReadBoolean(); resolvedIngredients = new CraftingRecipeIngredient[Width * Height]; for (int i = 0; i < resolvedIngredients.Length; i++) { bool isnull = reader.ReadBoolean(); if (isnull) { continue; } resolvedIngredients[i] = new CraftingRecipeIngredient(); resolvedIngredients[i].FromBytes(reader, resolver); } Name = new AssetLocation(reader.ReadString()); if (!reader.ReadBoolean()) { string json = reader.ReadString(); Attributes = new JsonObject(JToken.Parse(json)); } if (reader.ReadBoolean()) { RequiresTrait = reader.ReadString(); } }
/// <summary> /// Deserializes the alloy /// </summary> /// <param name="reader"></param> /// <param name="resolver"></param> public void FromBytes(BinaryReader reader, IWorldAccessor resolver) { Ingredient = new CraftingRecipeIngredient(); RecipeId = reader.ReadInt32(); Ingredient.FromBytes(reader, resolver); int len = reader.ReadInt32(); Pattern = new string[len][]; for (int i = 0; i < Pattern.Length; i++) { Pattern[i] = reader.ReadStringArray(); } Name = new AssetLocation(reader.ReadString()); Output = new JsonItemStack(); Output.FromBytes(reader, resolver.ClassRegistry); Output.Resolve(resolver, "[FromBytes]"); GenVoxels(); }
public CraftingRecipeIngredient Clone() { CraftingRecipeIngredient stack = new CraftingRecipeIngredient() { Code = Code.Clone(), Type = Type, Name = Name, Quantity = Quantity, IsWildCard = IsWildCard, IsTool = IsTool, ToolDurabilityCost = ToolDurabilityCost, AllowedVariants = AllowedVariants == null ? null : (string[])AllowedVariants.Clone(), ResolvedItemstack = ResolvedItemstack?.Clone(), ReturnedStack = ReturnedStack?.Clone() }; if (Attributes != null) { stack.Attributes = Attributes.Clone(); } return(stack); }
private bool MatchesShapeLess(ItemSlot[] suppliedSlots, int gridWidth) { int gridHeight = suppliedSlots.Length / gridWidth; if (gridWidth < Width || gridHeight < Height) { return(false); } List <KeyValuePair <ItemStack, CraftingRecipeIngredient> > ingredientStacks = new List <KeyValuePair <ItemStack, CraftingRecipeIngredient> >(); List <ItemStack> suppliedStacks = new List <ItemStack>(); // Step 1: Merge all stacks from the supplied slots for (int i = 0; i < suppliedSlots.Length; i++) { if (suppliedSlots[i].Itemstack != null) { bool found = false; for (int j = 0; j < suppliedStacks.Count; j++) { if (suppliedStacks[j].Satisfies(suppliedSlots[i].Itemstack)) { suppliedStacks[j].StackSize += suppliedSlots[i].Itemstack.StackSize; found = true; break; } } if (!found) { suppliedStacks.Add(suppliedSlots[i].Itemstack.Clone()); } } } // Step 2: Merge all stacks from the recipe reference for (int i = 0; i < resolvedIngredients.Length; i++) { CraftingRecipeIngredient ingredient = resolvedIngredients[i]; if (ingredient == null) { continue; } if (ingredient.IsWildCard) { bool foundw = false; int j = 0; for (; !foundw && j < suppliedStacks.Count; j++) { ItemStack inputStack = suppliedStacks[j]; foundw = ingredient.Type == inputStack.Class && WildcardUtil.Match(ingredient.Code, inputStack.Collectible.Code, ingredient.AllowedVariants) && inputStack.StackSize >= ingredient.Quantity ; foundw &= inputStack.Collectible.MatchesForCrafting(inputStack, this, ingredient); } if (!foundw) { return(false); } suppliedStacks.RemoveAt(j - 1); continue; } ItemStack stack = ingredient.ResolvedItemstack; bool found = false; for (int j = 0; j < ingredientStacks.Count; j++) { if (ingredientStacks[j].Key.Equals(world, stack, GlobalConstants.IgnoredStackAttributes)) { ingredientStacks[j].Key.StackSize += stack.StackSize; found = true; break; } } if (!found) { ingredientStacks.Add(new KeyValuePair <ItemStack, CraftingRecipeIngredient>(stack.Clone(), ingredient)); } } if (ingredientStacks.Count != suppliedStacks.Count) { return(false); } bool equals = true; for (int i = 0; equals && i < ingredientStacks.Count; i++) { bool found = false; for (int j = 0; !found && j < suppliedStacks.Count; j++) { found = ingredientStacks[i].Key.Satisfies(suppliedStacks[j]) && ingredientStacks[i].Key.StackSize <= suppliedStacks[j].StackSize && suppliedStacks[j].Collectible.MatchesForCrafting(suppliedStacks[j], this, ingredientStacks[i].Value) ; if (found) { suppliedStacks.RemoveAt(j); } } equals &= found; } return(equals); }
private bool ConsumeInputShapeLess(IPlayer byPlayer, ItemSlot[] inputSlots) { List <CraftingRecipeIngredient> exactMatchIngredients = new List <CraftingRecipeIngredient>(); List <CraftingRecipeIngredient> wildcardIngredients = new List <CraftingRecipeIngredient>(); for (int i = 0; i < resolvedIngredients.Length; i++) { CraftingRecipeIngredient ingredient = resolvedIngredients[i]; if (ingredient == null) { continue; } if (ingredient.IsWildCard || ingredient.IsTool) { wildcardIngredients.Add(ingredient.Clone()); continue; } ItemStack stack = ingredient.ResolvedItemstack; bool found = false; for (int j = 0; j < exactMatchIngredients.Count; j++) { if (exactMatchIngredients[j].ResolvedItemstack.Satisfies(stack)) { exactMatchIngredients[j].ResolvedItemstack.StackSize += stack.StackSize; found = true; break; } } if (!found) { exactMatchIngredients.Add(ingredient.Clone()); } } for (int i = 0; i < inputSlots.Length; i++) { ItemStack inStack = inputSlots[i].Itemstack; if (inStack == null) { continue; } for (int j = 0; j < exactMatchIngredients.Count; j++) { if (exactMatchIngredients[j].ResolvedItemstack.Satisfies(inStack)) { int quantity = Math.Min(exactMatchIngredients[j].ResolvedItemstack.StackSize, inStack.StackSize); inStack.Collectible.OnConsumedByCrafting(inputSlots, inputSlots[i], this, exactMatchIngredients[j], byPlayer, quantity); exactMatchIngredients[j].ResolvedItemstack.StackSize -= quantity; if (exactMatchIngredients[j].ResolvedItemstack.StackSize <= 0) { exactMatchIngredients.RemoveAt(j); } break; } } for (int j = 0; j < wildcardIngredients.Count; j++) { CraftingRecipeIngredient ingredient = wildcardIngredients[j]; if ( ingredient.Type == inStack.Class && WildcardUtil.Match(ingredient.Code, inStack.Collectible.Code, ingredient.AllowedVariants) && inStack.StackSize >= ingredient.Quantity ) { int quantity = Math.Min(ingredient.Quantity, inStack.StackSize); inStack.Collectible.OnConsumedByCrafting(inputSlots, inputSlots[i], this, ingredient, byPlayer, quantity); if (ingredient.IsTool) { wildcardIngredients.RemoveAt(j); } else { ingredient.Quantity -= quantity; if (ingredient.Quantity <= 0) { wildcardIngredients.RemoveAt(j); } } break; } } } return(exactMatchIngredients.Count == 0); }