66import gregtech .api .recipes .builders .*;
77import gregtech .api .render .*;
88import gregtech .api .util .world .DummyWorld ;
9+ import gregtech .common .metatileentities .electric .MetaTileEntityMacerator ;
910import net .minecraft .init .*;
1011import net .minecraft .item .*;
11- import net .minecraft .tileentity .TileEntity ;
1212import net .minecraft .util .*;
1313import net .minecraft .world .World ;
1414import org .junit .jupiter .api .*;
15+ import org .junit .jupiter .params .*;
16+ import org .junit .jupiter .params .provider .*;
17+
18+ import java .lang .reflect .InvocationTargetException ;
19+ import java .util .stream .Stream ;
1520
1621import static org .junit .jupiter .api .Assertions .*;
22+ import static gregtech .api .GTValues .*;
1723
1824public class AbstractRecipeLogicTest {
1925
@@ -198,4 +204,196 @@ protected long getMaxVoltage() {
198204 assertEquals (GTValues .V [GTValues .ZPM ] / 2 , oc [0 ]);
199205 assertEquals (1 , oc [1 ]);
200206 }
207+
208+ /** Base chance for standard_chanced_outputs test */
209+ private static final int BASE_CHANCE = 7500 ;
210+ /** Bonus chance per tier for standard_chanced_outputs test */
211+ private static final int BONUS_CHANCE = 500 ;
212+
213+ /** Argument stream for the standard_chanced_outputs test */
214+ static Stream <Arguments > standardChancedArgs () {
215+ return Stream .of (
216+ Arguments .of ( LV , BASE_CHANCE + BONUS_CHANCE * 0 ),
217+ Arguments .of ( MV , BASE_CHANCE + BONUS_CHANCE * 1 ), // starts to gain bonuses here
218+ Arguments .of ( HV , BASE_CHANCE + BONUS_CHANCE * 2 ),
219+ Arguments .of ( EV , BASE_CHANCE + BONUS_CHANCE * 3 ),
220+ Arguments .of ( IV , BASE_CHANCE + BONUS_CHANCE * 4 ), // hits speed cap here
221+ Arguments .of (LuV , BASE_CHANCE + BONUS_CHANCE * 5 ), // hits chance cap here
222+ Arguments .of (ZPM , BASE_CHANCE + BONUS_CHANCE * 5 ),
223+ Arguments .of ( UV , BASE_CHANCE + BONUS_CHANCE * 5 ));
224+ }
225+
226+ /**
227+ * Test to verify AbstractRecipeLogic handles chanced output computations appropriately.
228+ */
229+ @ ParameterizedTest
230+ @ MethodSource ("standardChancedArgs" )
231+ public void standard_chanced_outputs (int tier , int chanceExpected ) {
232+ World world = DummyWorld .INSTANCE ;
233+
234+ // Create an empty recipe map to work with
235+ RecipeMap <SimpleRecipeBuilder > map = new RecipeMap <>("fakemachine" ,
236+ 1 ,
237+ 1 ,
238+ 1 ,
239+ 3 ,
240+ 0 ,
241+ 0 ,
242+ 0 ,
243+ 0 ,
244+ new SimpleRecipeBuilder ());
245+
246+ var machine = GregTechAPI .registerMetaTileEntity (70 +tier ,
247+ new SimpleMachineMetaTileEntity (new ResourceLocation (GTValues .MODID , "fakemachine." + GTValues .VN [tier ].toLowerCase ()),
248+ map , Textures .CHEMICAL_REACTOR_OVERLAY , tier ));
249+
250+ MetaTileEntity macerTE = new MetaTileEntityHolder ().setMetaTileEntity (machine );
251+ macerTE .getHolder ().setWorld (world );
252+
253+ // stone makes cobblestone and has a chance of gravel
254+ map .recipeBuilder ()
255+ .inputs (new ItemStack (Blocks .STONE ))
256+ .outputs (new ItemStack (Blocks .COBBLESTONE ))
257+ .chancedOutput (new ItemStack (Blocks .GRAVEL ), BASE_CHANCE , BONUS_CHANCE )
258+ .EUt (30 ).duration (150 ) // LV base recipe
259+ .buildAndRegister ();
260+
261+ AbstractRecipeLogic arl = new AbstractRecipeLogic (macerTE , map ) {
262+ @ Override
263+ protected long getEnergyStored () {
264+ return Long .MAX_VALUE ;
265+ }
266+
267+ @ Override
268+ protected long getEnergyCapacity () {
269+ return Long .MAX_VALUE ;
270+ }
271+
272+ @ Override
273+ protected boolean drawEnergy (int recipeEUt ) {
274+ return true ;
275+ }
276+
277+ @ Override
278+ protected long getMaxVoltage () {
279+ return GTValues .V [tier ];
280+ }
281+ };
282+
283+ arl .isOutputsFull = false ;
284+ arl .invalidInputsForRecipes = false ;
285+
286+ // put a stack of stone in the machine
287+ arl .getInputInventory ().insertItem (0 , new ItemStack (Blocks .STONE , 16 ), false );
288+ arl .trySearchNewRecipe ();
289+ // ensure that it found a recipe and consumed inputs
290+ assertTrue (arl .isActive );
291+
292+ // get the computed chance of the gravel stack
293+ var chancedOut = arl .chancedItemOutputs .get (0 );
294+ assertEquals (chanceExpected , chancedOut .getRight ());
295+ }
296+
297+ /** Base chance for macerator_chanced_outputs test */
298+ private static final int MACER_BASE_CHANCE = 1400 ;
299+ /** Bonus chance per tier for macerator_chanced_outputs test */
300+ private static final int MACER_BONUS_CHANCE = 850 ;
301+
302+ /** Argument stream for the macerator_chanced_outputs test */
303+ static Stream <Arguments > macerChancedArgs () {
304+ return Stream .of (
305+ Arguments .of (1 , LV , MACER_BASE_CHANCE + MACER_BONUS_CHANCE * 0 ),
306+ Arguments .of (1 , MV , MACER_BASE_CHANCE + MACER_BONUS_CHANCE * 0 ),
307+ Arguments .of (3 , HV , MACER_BASE_CHANCE + MACER_BONUS_CHANCE * 1 ), // starts to gain bonuses here
308+ Arguments .of (3 , EV , MACER_BASE_CHANCE + MACER_BONUS_CHANCE * 2 ),
309+ Arguments .of (3 , IV , MACER_BASE_CHANCE + MACER_BONUS_CHANCE * 3 ),
310+ Arguments .of (3 , LuV , MACER_BASE_CHANCE + MACER_BONUS_CHANCE * 4 ),
311+ Arguments .of (3 , ZPM , MACER_BASE_CHANCE + MACER_BONUS_CHANCE * 5 ),
312+ Arguments .of (3 , UV , MACER_BASE_CHANCE + MACER_BONUS_CHANCE * 6 ));
313+ }
314+
315+ /**
316+ * Test to verify Macerators handle chanced output computations appropriately.
317+ */
318+ @ ParameterizedTest
319+ @ MethodSource ("macerChancedArgs" )
320+ public void macerator_chanced_outputs (int outputs , int tier , int chanceExpected ) throws
321+ NoSuchMethodException ,
322+ InvocationTargetException ,
323+ IllegalAccessException {
324+ World world = DummyWorld .INSTANCE ;
325+
326+ // Create an empty recipe map to work with
327+ RecipeMap <SimpleRecipeBuilder > map = new RecipeMap <>("macerator_2" ,
328+ 1 ,
329+ 1 ,
330+ 1 ,
331+ 3 ,
332+ 0 ,
333+ 0 ,
334+ 0 ,
335+ 0 ,
336+ new SimpleRecipeBuilder ());
337+
338+ var macer = GregTechAPI .registerMetaTileEntity (60 +tier ,
339+ new MetaTileEntityMacerator (new ResourceLocation (GTValues .MODID , "macerator." + GTValues .VN [tier ].toLowerCase ()),
340+ map , outputs , Textures .MACERATOR_OVERLAY , tier ));
341+
342+ MetaTileEntity macerTE = new MetaTileEntityHolder ().setMetaTileEntity (macer );
343+ macerTE .getHolder ().setWorld (world );
344+
345+ // stone makes cobblestone and has a chance of gravel
346+ map .recipeBuilder ()
347+ .inputs (new ItemStack (Blocks .STONE ))
348+ .outputs (new ItemStack (Blocks .COBBLESTONE ))
349+ .chancedOutput (new ItemStack (Blocks .GRAVEL ), MACER_BASE_CHANCE , MACER_BONUS_CHANCE )
350+ .EUt (12 ).duration (200 ) // ULV-scaling LV-base-tier recipe, emulating crushedCentrifuged macer recipes
351+ .buildAndRegister ();
352+
353+ // get at the Macerator custom workable logic
354+ var workableFn = MetaTileEntityMacerator .class .getDeclaredMethod ("createWorkable" , RecipeMap .class );
355+ workableFn .setAccessible (true );
356+ RecipeLogicEnergy workable = (RecipeLogicEnergy ) workableFn .invoke (macer , map );
357+
358+ AbstractRecipeLogic arl = new AbstractRecipeLogic (macerTE , map ) {
359+
360+ @ Override
361+ protected int getMachineTierForRecipe (Recipe recipe ) {
362+ return workable .getMachineTierForRecipe (recipe );
363+ }
364+
365+ @ Override
366+ protected long getEnergyStored () {
367+ return Long .MAX_VALUE ;
368+ }
369+
370+ @ Override
371+ protected long getEnergyCapacity () {
372+ return Long .MAX_VALUE ;
373+ }
374+
375+ @ Override
376+ protected boolean drawEnergy (int recipeEUt ) {
377+ return true ;
378+ }
379+
380+ @ Override
381+ protected long getMaxVoltage () {
382+ return GTValues .V [tier ];
383+ }
384+ };
385+
386+ arl .isOutputsFull = false ;
387+ arl .invalidInputsForRecipes = false ;
388+
389+ // put a stack of stone in the machine
390+ arl .getInputInventory ().insertItem (0 , new ItemStack (Blocks .STONE , 16 ), false );
391+ arl .trySearchNewRecipe ();
392+ // ensure that it found a recipe and consumed inputs
393+ assertTrue (arl .isActive );
394+
395+ // get the computed chance of the gravel stack
396+ var chancedOut = arl .chancedItemOutputs .get (0 );
397+ assertEquals (chanceExpected , chancedOut .getRight ());
398+ }
201399}
0 commit comments