11package mekanism .common .content .assemblicator ;
22
33import java .util .List ;
4- import java .util .Objects ;
54import mekanism .api .inventory .IInventorySlot ;
65import mekanism .common .attachments .FormulaAttachment ;
76import mekanism .common .recipe .MekanismRecipeType ;
87import mekanism .common .util .MekanismUtils ;
98import net .minecraft .core .NonNullList ;
10- import net .minecraft .core .RegistryAccess ;
119import net .minecraft .world .item .ItemStack ;
1210import net .minecraft .world .item .crafting .CraftingInput ;
1311import net .minecraft .world .item .crafting .CraftingRecipe ;
1614import net .minecraft .world .level .Level ;
1715import org .jetbrains .annotations .Nullable ;
1816
19- public class RecipeFormula {
17+ public record RecipeFormula ( CraftingInput . Positioned craftingInput , @ Nullable RecipeHolder < CraftingRecipe > recipe ) {
2018
21- public static final RecipeFormula EMPTY = new RecipeFormula ();
19+ public static final RecipeFormula EMPTY = new RecipeFormula (CraftingInput . Positioned . EMPTY , null );
2220
23- public final CraftingInput .Positioned craftingInput ;
24- @ Nullable
25- public final RecipeHolder <CraftingRecipe > recipe ;
26-
27- private RecipeFormula () {
28- craftingInput = CraftingInput .Positioned .EMPTY ;
29- recipe = null ;
21+ public static RecipeFormula create (Level world , FormulaAttachment attachment ) {
22+ //Should always be a 3x3 grid for the size
23+ return create (world , MekanismUtils .getCraftingInput (3 , 3 , attachment .inventory (), true ));
3024 }
3125
32- public RecipeFormula (Level world , FormulaAttachment attachment ) {
26+ public static RecipeFormula create (Level world , List < IInventorySlot > craftingGridSlots ) {
3327 //Should always be a 3x3 grid for the size
34- craftingInput = MekanismUtils .getCraftingInput (3 , 3 , attachment .inventory (), true );
35- recipe = getRecipeFromGrid (craftingInput , world );
28+ return create (world , MekanismUtils .getCraftingInputSlots (3 , 3 , craftingGridSlots , true ));
3629 }
3730
38- private RecipeFormula (Level world , CraftingInput .Positioned craftingInput ) {
39- this .craftingInput = craftingInput ;
40- recipe = getRecipeFromGrid (this .craftingInput , world );
31+ public static RecipeFormula create (Level world , CraftingInput .Positioned craftingInput ) {
32+ if (craftingInput .input ().isEmpty ()) {
33+ return EMPTY ;
34+ }
35+ return new RecipeFormula (craftingInput , MekanismRecipeType .getRecipeFor (RecipeType .CRAFTING , craftingInput .input (), world ).orElse (null ));
4136 }
4237
43- public RecipeFormula (Level world , List <IInventorySlot > craftingGridSlots ) {
44- //Should always be a 3x3 grid for the size
45- craftingInput = MekanismUtils .getCraftingInputSlots (3 , 3 , craftingGridSlots , true );
46- recipe = getRecipeFromGrid (craftingInput , world );
38+ public RecipeFormula withStack (Level world , int index , ItemStack stack ) {
39+ if (isEmpty () && stack .isEmpty ()) {
40+ return this ;
41+ }
42+ List <ItemStack > copy = getCopy (false );
43+ ItemStack old = copy .set (index , stack );
44+ if (old != null && ItemStack .isSameItemSameComponents (old , stack )) {
45+ //Nothing changed, don't bother creating new objects
46+ //TODO: If there is a performance problem, try to optimize this to being above copying the list
47+ return this ;
48+ }
49+ return create (world , CraftingInput .ofPositioned (3 , 3 , copy ));
4750 }
4851
4952 public ItemStack getInputStack (int slot ) {
53+ if (isEmpty ()) {
54+ return ItemStack .EMPTY ;
55+ }
5056 int row = slot / 3 ;
5157 int column = slot % 3 ;
5258 CraftingInput input = craftingInput .input ();
@@ -57,6 +63,14 @@ public ItemStack getInputStack(int slot) {
5763 return input .getItem (column - craftingInput .left (), row - craftingInput .top ());
5864 }
5965
66+ public boolean isEmpty () {
67+ return this == EMPTY ;
68+ }
69+
70+ public boolean valid () {
71+ return recipe != null ;
72+ }
73+
6074 public boolean matches (Level world , List <IInventorySlot > craftingGridSlots ) {
6175 if (recipe == null ) {
6276 return false ;
@@ -65,17 +79,6 @@ public boolean matches(Level world, List<IInventorySlot> craftingGridSlots) {
6579 return recipe .value ().matches (MekanismUtils .getCraftingInputSlots (3 , 3 , craftingGridSlots , true ).input (), world );
6680 }
6781
68- //Must have matches be called before this and be true as it assumes that the dummy inventory was set by it
69- public ItemStack assemble (RegistryAccess registryAccess ) {
70- return recipe == null ? ItemStack .EMPTY : recipe .value ().assemble (craftingInput .input (), registryAccess );
71- }
72-
73- //Must have matches be called before this and be true as it assumes that the dummy inventory was set by it
74- public NonNullList <ItemStack > getRemainingItems () {
75- //Should never be null given the assumption matches is called first
76- return recipe == null ? NonNullList .create () : recipe .value ().getRemainingItems (craftingInput .input ());
77- }
78-
7982 public boolean isIngredientInPos (Level world , ItemStack stack , int i ) {
8083 if (recipe == null ) {
8184 return false ;
@@ -123,36 +126,12 @@ public boolean isValidIngredient(Level world, ItemStack stack) {
123126 return false ;
124127 }
125128
126- public boolean isValidFormula () {
127- return getRecipe () != null ;
128- }
129-
130- @ Nullable
131- public RecipeHolder <CraftingRecipe > getRecipe () {
132- return recipe ;
133- }
134-
135- public boolean isFormulaEqual (RecipeFormula formula ) {
136- return Objects .equals (formula .getRecipe (), getRecipe ());
137- }
138-
139- public RecipeFormula withStack (Level world , int index , ItemStack stack ) {
140- if (this == EMPTY && stack .isEmpty ()) {
141- return this ;
142- }
143- List <ItemStack > copy = getCopy (false );
144- copy .set (index , stack );
145- return new RecipeFormula (world , CraftingInput .ofPositioned (3 , 3 , copy ));
146- }
147-
148- @ Nullable
149- private static RecipeHolder <CraftingRecipe > getRecipeFromGrid (CraftingInput .Positioned input , Level world ) {
150- return MekanismRecipeType .getRecipeFor (RecipeType .CRAFTING , input .input (), world ).orElse (null );
151- }
152-
153129 public List <ItemStack > getCopy (boolean copyStacks ) {
154- CraftingInput input = craftingInput .input ();
155130 List <ItemStack > stacks = NonNullList .withSize (9 , ItemStack .EMPTY );
131+ if (isEmpty ()) {
132+ return stacks ;
133+ }
134+ CraftingInput input = craftingInput .input ();
156135 for (int row = 0 ; row < input .height (); row ++) {
157136 int shiftedRow = 3 * (craftingInput .top () + row );
158137 for (int column = 0 ; column < input .width (); column ++) {
0 commit comments