11/*
2- Code adapted from Nomi-Labs https://github.com/Nomi-CEu/Nomi-Labs @ 6e14c06
2+ Code adapted from Nomi-Labs https://github.com/Nomi-CEu/Nomi-Labs @ d2d6e89
33 */
44package gregtech .integration .theoneprobe .provider ;
55
1010import gregtech .integration .nomilabs .element .*;
1111import it .unimi .dsi .fastutil .objects .Object2ObjectLinkedOpenHashMap ;
1212import mcjty .theoneprobe .api .*;
13+ import mcjty .theoneprobe .apiimpl .elements .ElementItemStack ;
1314import mcjty .theoneprobe .apiimpl .styles .*;
1415import mcjty .theoneprobe .config .Config ;
1516import net .minecraft .entity .player .EntityPlayer ;
1617import net .minecraft .item .ItemStack ;
1718import net .minecraft .tileentity .TileEntity ;
1819import net .minecraftforge .common .capabilities .Capability ;
1920import net .minecraftforge .fluids .*;
21+ import org .apache .commons .lang3 .tuple .Pair ;
2022import org .jetbrains .annotations .NotNull ;
2123
2224import java .util .*;
23- import java .util .function .BiConsumer ;
25+ import java .util .function .Function ;
2426
2527import static mcjty .theoneprobe .api .ElementAlignment .*;
2628import static mcjty .theoneprobe .api .TextStyleClass .*;
29+ import static gregtech .integration .nomilabs .element .LabsChancedItemStackElement .formatChance ;
2730
2831public class RecipeOutputsProvider extends CapabilityInfoProvider <IWorkable > {
2932
@@ -48,71 +51,67 @@ protected void addProbeInfo(IWorkable capability, IProbeInfo info, EntityPlayer
4851 // Generators, Ignore
4952 if (recipe .getRecipeEUt () < 0 ) return ;
5053
51- var outputs = getUniqueItems (recipe .getItemOutputs ());
52- var fluidOutputs = getUniqueFluids (recipe .getFluidOutputs ());
54+ var lists = createItemFluidElementLists (recipe );
55+ var items = lists .getLeft ();
56+ var fluids = lists .getRight ();
5357
54- if (outputs .isEmpty () && fluidOutputs .isEmpty ()) return ;
58+ if (items .isEmpty () && fluids .isEmpty ()) return ;
5559
56- boolean showDetailed = outputs .size () + fluidOutputs .size () <= Config .showItemDetailThresshold &&
57- player .isSneaking ();
60+ boolean showDetailed = items .size () + fluids .size () <= Config .showItemDetailThresshold && player .isSneaking ();
5861 IProbeInfo mainPanel = info .vertical ()
5962 .text ("{*gregtech.top.crafting*}" )
6063 .vertical (info .defaultLayoutStyle ().borderColor (Config .chestContentsBorderColor )
6164 .spacing (5 ));
6265
6366 if (showDetailed ) {
64- for (var entry : outputs .entrySet ()) {
65- ItemStack stack = entry .getKey ().toStack (entry .getValue ());
67+ for (var entry : items )
6668 mainPanel .horizontal (new LayoutStyle ().spacing (10 ).alignment (ALIGN_CENTER ))
67- .item (stack , new ItemStyle ().width (16 ).height (16 ))
68- .text (INFO + stack .getDisplayName ());
69- }
69+ .element (entry .getValue ())
70+ .text (INFO + entry .getKey ());
7071
71- for (var entry : fluidOutputs .entrySet ()) {
72- FluidStack stack = new FluidStack (entry .getKey (), entry .getValue ());
72+ for (var entry : fluids )
7373 mainPanel .horizontal (new LayoutStyle ().spacing (10 ).alignment (ALIGN_CENTER ))
74- .element (new LabsFluidStackElement ( stack ))
75- .element (new LabsFluidNameElement ( stack , false ));
76- }
74+ .element (entry . getValue ( ))
75+ .element (entry . getKey ( ));
76+
7777 return ;
7878 }
7979
8080 // If outputs and fluid outputs are both of size 1, show on same row instead of over two rows
81- boolean condense = outputs .size () == 1 && fluidOutputs .size () == 1 ;
81+ boolean condense = items .size () == 1 && fluids .size () == 1 ;
8282 IProbeInfo sharedHorizontal = null ;
8383
8484 if (condense )
8585 sharedHorizontal = createHorizontalLayout (mainPanel );
8686
87- if (!outputs .isEmpty ()) {
87+ if (!items .isEmpty ()) {
8888 IProbeInfo panel ;
8989 if (condense )
9090 panel = sharedHorizontal ;
9191 else
9292 panel = createHorizontalLayout (mainPanel );
9393
94- addOutputs (outputs , ( meta , amt ) -> panel . item ( meta . toStack ( amt ), new ItemStyle (). width ( 16 ). height ( 16 )) );
94+ addOutputs (items , panel , Pair :: getValue );
9595 }
9696
97- if (!fluidOutputs .isEmpty ()) {
97+ if (!fluids .isEmpty ()) {
9898 IProbeInfo panel ;
9999 if (condense )
100100 panel = sharedHorizontal ;
101101 else
102102 panel = createHorizontalLayout (mainPanel );
103103
104- addOutputs (fluidOutputs ,
105- (fluid , amount ) -> panel .element (new LabsFluidStackElement (new FluidStack (fluid , amount ))));
104+ addOutputs (fluids , panel , Pair ::getValue );
106105 }
107106 }
108107
109- private <T > void addOutputs (Map < T , Integer > outputs , BiConsumer <T , Integer > addToPanel ) {
108+ private <T > void addOutputs (List < T > list , IProbeInfo panel , Function <T , IElement > getElement ) {
110109 int idx = 0 ;
111110
112- for (var output : outputs . entrySet () ) {
111+ for (var entry : list ) {
113112 if (idx >= AMT_IN_ROW ) break ;
114113
115- addToPanel . accept ( output . getKey (), output . getValue ( ));
114+ panel . element ( getElement . apply ( entry ));
116115 idx ++;
117116 }
118117 }
@@ -121,6 +120,63 @@ private IProbeInfo createHorizontalLayout(IProbeInfo mainPanel) {
121120 return mainPanel .horizontal (new LayoutStyle ().spacing (4 ));
122121 }
123122
123+ private Pair <List <Pair <String , ElementItemStack >>, List <Pair <LabsFluidNameElement , LabsFluidStackElement >>> createItemFluidElementLists (AbstractRecipeLogic recipe ) {
124+ // Items
125+ var outputs =
126+ getUnique (recipe .getItemOutputs ().subList (0 , recipe .getNonChancedItemAmt ()),
127+ ItemStack ::isEmpty , ItemMeta ::new , ItemStack ::getCount );
128+
129+ var chancedOutputs =
130+ getUnique (recipe .getChancedItemOutputs (),
131+ (chanced ) -> chanced .getKey ().isEmpty () || chanced .getValue () == 0 ,
132+ (chanced ) -> Pair .of (new ItemMeta (chanced .getKey ()), chanced .getValue ()),
133+ (chanced ) -> chanced .getKey ().getCount ());
134+
135+ IItemStyle style = new ItemStyle ().width (16 ).height (16 );
136+ List <Pair <String , ElementItemStack >> items = new ArrayList <>();
137+
138+ for (var output : outputs .entrySet ()) {
139+ ItemStack stack = output .getKey ().toStack (output .getValue ());
140+ items .add (Pair .of (stack .getDisplayName (), new ElementItemStack (stack , style )));
141+ }
142+
143+ for (var chanced : chancedOutputs .entrySet ()) {
144+ ItemStack stack = chanced .getKey ().getKey ().toStack (chanced .getValue ());
145+ String display = stack .getDisplayName () + " (" + formatChance (chanced .getKey ().getValue ()) + ")" ;
146+ items .add (Pair .of (display , new LabsChancedItemStackElement (stack , chanced .getKey ().getValue (), style )));
147+ }
148+
149+ // Fluids
150+ var fluidOutputs =
151+ getUnique (recipe .getFluidOutputs (),
152+ (stack ) -> stack .amount == 0 , FluidStack ::getFluid , (stack ) -> stack .amount );
153+
154+ List <Pair <LabsFluidNameElement , LabsFluidStackElement >> fluids = new ArrayList <>();
155+
156+ for (var output : fluidOutputs .entrySet ()) {
157+ FluidStack stack = new FluidStack (output .getKey (), output .getValue ());
158+ fluids .add (Pair .of (new LabsFluidNameElement (stack , false ), new LabsFluidStackElement (stack )));
159+ }
160+
161+ return Pair .of (items , fluids );
162+ }
163+
164+ private <T , K > Map <K , Integer > getUnique (List <T > stacks , Function <T , Boolean > emptyCheck , Function <T , K > getKey ,
165+ Function <T , Integer > getCount ) {
166+ Map <K , Integer > map = new Object2ObjectLinkedOpenHashMap <>();
167+
168+ for (T stack : stacks ) {
169+ if (emptyCheck .apply (stack )) continue ;
170+
171+ map .compute (getKey .apply (stack ), (key , count ) -> {
172+ if (count == null ) count = 0 ;
173+ return count + getCount .apply (stack );
174+ });
175+ }
176+
177+ return map ;
178+ }
179+
124180 private Map <ItemMeta , Integer > getUniqueItems (List <ItemStack > stacks ) {
125181 Map <ItemMeta , Integer > map = new Object2ObjectLinkedOpenHashMap <>();
126182
0 commit comments