/// <summary>
 /// Replaces an existing CraftPerformer on this CraftMenuInfo.
 /// </summary>
 /// <param name="index">The index of the CraftPerformer to replace</param>
 /// <param name="SlotValidator">A Func that is used to check if an item is valid for a slot.</param>
 /// <param name="CraftValidator">A Func that is used to check if the items currently in the slots are valid for a recipe. The Item array is of length 4, where the first three Items are the inputs, and the fourth Item is the output.</param>
 /// <param name="CraftPerformer">An Action that is used to perform a crafting operation by modifying the contents of the Item array. The Item array is of length 4, where the first three Items are the inputs, and the fourth Item is the output. Should decrement the inputs, and set the output, possibly respecting whatever is already in the output.</param>
 /// <param name="CraftFinalizer">Used to perform any final behavior after the craft is complete. The Item array is of length 4, where the first three Items are the inputs, and the fourth Item is the output.</param>
 public int ReplaceCraftPerformer(int index, SlotValidator SlotValidator, CraftValidator CraftValidator, CraftPerformer CraftPerformer, CraftFinalizer CraftFinalizer = null)
 {
     SlotValidators[index]       = SlotValidator ?? throw new ArgumentNullException("SlotValidator cannot be null!");
     CraftValidators[index]      = CraftValidator ?? throw new ArgumentNullException("CraftValidator cannot be null!");
     CraftPerformers[index]      = CraftPerformer ?? throw new ArgumentNullException("CraftPerformer cannot be null!");
     CraftFinalizers[index]      = CraftFinalizer;
     CraftPerformerModIDs[index] = Registry.modRegistering;
     return(CraftPerformers.Count - 1);
 }
 /// <summary>
 /// Registers another CraftPerformer to this CraftMenuInfo. Returns the index that the performer was registered to.
 /// </summary>
 /// <param name="SlotValidator">Used to check if an item is valid for a slot.</param>
 /// <param name="CraftValidator">Used to check if the items currently in the slots are valid for a recipe. The Item array is of length 4, where the first three Items are the inputs, and the fourth Item is the output.</param>
 /// <param name="CraftPerformer">Used to perform a crafting operation by modifying the contents of the Item array. The Item array is of length 4, where the first three Items are the inputs, and the fourth Item is the output. Should decrement the inputs, and set the output, possibly respecting whatever is already in the output.</param>
 /// <param name="CraftFinalizer">Optionally used to perform any final behavior after the craft is complete. The Item array is of length 4, where the first three Items are the inputs, and the fourth Item is the output.</param>
 public int AddCraftPerformer(SlotValidator SlotValidator, CraftValidator CraftValidator, CraftPerformer CraftPerformer, CraftFinalizer CraftFinalizer = null)
 {
     if (SlotValidator == null)
     {
         throw new ArgumentNullException("SlotValidator cannot be null!");
     }
     if (CraftValidator == null)
     {
         throw new ArgumentNullException("CraftValidator cannot be null!");
     }
     if (CraftPerformer == null)
     {
         throw new ArgumentNullException("CraftPerformer cannot be null!");
     }
     SlotValidators.Add(SlotValidator);
     CraftValidators.Add(CraftValidator);
     CraftPerformers.Add(CraftPerformer);
     CraftFinalizers.Add(CraftFinalizer);
     CraftPerformerModIDs.Add(Registry.modRegistering);
     CraftPerformerInitModIDs.Add(Registry.modRegistering);
     return(CraftPerformers.Count - 1);
 }
 /// <summary>
 /// Use to register a custom crafting menu. Using RegisterMenu is unnecessary for crafting menus. Note that all crafting menus must have, at most, 3 ingredient slots. Use OpenCraftMenu to open the menu.
 /// </summary>
 /// <param name="Title">The text to display as the title of the crafting window.</param>
 /// <param name="Desc">The text to display as the description of the crafting window.</param>
 /// <param name="MenuMat">The Material to use for the crafting window.</param>
 /// <param name="ProgressBarMat">The Material to use for the crafting progress bar.</param>
 /// <param name="ButtonInactiveMat">The Material to be used to display the inactive craft button.</param>
 /// <param name="ButtonActiveMat">The Material to be used to display the active craft button.</param>
 /// <param name="ButtonSelectMat">The Material to be used to display the selected craft button.</param>
 /// <param name="CraftSound">The sound effect that plays every time the craft button is pressed.</param>
 /// <param name="SlotValidator">Used to check if an item is valid for a slot.</param>
 /// <param name="CraftValidator">Used to check if the items currently in the slots are valid for a recipe. The Item array is of length 4, where the first three Items are the inputs, and the fourth Item is the output.</param>
 /// <param name="CraftPerformer">Used to perform a crafting operation by modifying the contents of the Item array. The Item array is of length 4, where the first three Items are the inputs, and the fourth Item is the output. Should decrement the inputs, and set the output, possibly respecting whatever is already in the output.</param>
 /// <param name="CraftFinalizer">Optionally used to perform any final behavior after the craft is complete. The Item array is of length 4, where the first three Items are the inputs, and the fourth Item is the output.</param>
 /// <param name="Tile">An optional parameter that specifies what Interactive tile should open the menu when interacted with.</param>
 public CraftMenuInfo(string Title, string Desc, Material MenuMat, Material ProgressBarMat, Material ButtonInactiveMat, Material ButtonActiveMat, Material ButtonSelectMat, AudioClip CraftSound, SlotValidator SlotValidator, CraftValidator CraftValidator, CraftPerformer CraftPerformer, CraftFinalizer CraftFinalizer = null, TileInfo Tile = null) : base(MenuType.CRAFTING, null, Tile)
 {
     this.Title             = Title;
     this.Desc              = Desc;
     this.MenuMat           = MenuMat;
     this.ProgressBarMat    = ProgressBarMat;
     this.ButtonInactiveMat = ButtonInactiveMat;
     this.ButtonActiveMat   = ButtonActiveMat;
     this.ButtonSelectMat   = ButtonSelectMat;
     this.CraftSound        = CraftSound;
     if (SlotValidator != null && CraftValidator != null && CraftPerformer != null)
     {
         SlotValidators           = new List <SlotValidator>(1);
         CraftValidators          = new List <CraftValidator>(1);
         CraftPerformers          = new List <CraftPerformer>(1);
         CraftFinalizers          = new List <CraftFinalizer>(1);
         CraftPerformerModIDs     = new List <int>(1);
         CraftPerformerInitModIDs = new List <int>(1);
         AddCraftPerformer(SlotValidator, CraftValidator, CraftPerformer, CraftFinalizer);
     }
     else if (SlotValidator != null || CraftValidator != null || CraftPerformer != null)
     {
         throw new InvalidOperationException("If SlotValidator, CraftValidator, or CraftPerformer are null, they must all be null!");
     }
     else
     {
         SlotValidators           = new List <SlotValidator>(0);
         CraftValidators          = new List <CraftValidator>(0);
         CraftPerformers          = new List <CraftPerformer>(0);
         CraftFinalizers          = new List <CraftFinalizer>(0);
         CraftPerformerModIDs     = new List <int>(0);
         CraftPerformerInitModIDs = new List <int>(0);
     }
 }