11package com .workert .robotics .base .registries ;
22
3+ import com .simibubi .create .foundation .data .CreateRegistrate ;
4+ import com .tterrag .registrate .util .entry .ItemProviderEntry ;
5+ import com .tterrag .registrate .util .entry .RegistryEntry ;
36import com .workert .robotics .Robotics ;
7+ import it .unimi .dsi .fastutil .objects .*;
8+ import net .minecraft .client .Minecraft ;
9+ import net .minecraft .client .renderer .entity .ItemRenderer ;
10+ import net .minecraft .client .resources .model .BakedModel ;
411import net .minecraft .core .registries .Registries ;
512import net .minecraft .network .chat .Component ;
6- import net .minecraft .world .item .CreativeModeTab ;
7- import net .minecraft .world .item .CreativeModeTabs ;
13+ import net .minecraft .world .item .*;
14+ import net .minecraft .world .level .block .Block ;
15+ import net .minecraftforge .api .distmarker .Dist ;
816import net .minecraftforge .eventbus .api .IEventBus ;
17+ import net .minecraftforge .fml .DistExecutor ;
918import net .minecraftforge .fml .common .Mod ;
1019import net .minecraftforge .registries .DeferredRegister ;
1120import net .minecraftforge .registries .RegistryObject ;
21+ import org .apache .commons .lang3 .mutable .MutableObject ;
22+
23+ import java .util .LinkedList ;
24+ import java .util .List ;
25+ import java .util .Map ;
26+ import java .util .Set ;
27+ import java .util .function .Function ;
28+ import java .util .function .Predicate ;
1229
1330@ Mod .EventBusSubscriber (bus = Mod .EventBusSubscriber .Bus .MOD )
1431public class CreativeModeTabRegistry {
@@ -17,13 +34,195 @@ public class CreativeModeTabRegistry {
1734
1835 public static final RegistryObject <CreativeModeTab > BASE_CREATIVE_TAB = CREATIVE_MODE_TABS .register ("base" ,
1936 () -> CreativeModeTab .builder ()
20- .title (Component .translatable ("itemGroup.create .base" ))
37+ .title (Component .translatable ("itemGroup.robotics .base" ))
2138 .withTabsBefore (CreativeModeTabs .SPAWN_EGGS )
22- .icon (BlockRegistry . TIN_ORE ::asStack )
23- // .displayItems(new RegistrateDisplayItemsGenerator(true, CreativeModeTabRegistry.BASE_CREATIVE_TAB))
39+ .icon (ItemRegistry . CLOCKCOPTER ::asStack )
40+ .displayItems (new RegistrateDisplayItemsGenerator (true , CreativeModeTabRegistry .BASE_CREATIVE_TAB ))
2441 .build ());
2542
2643 public static void register (IEventBus modEventBus ) {
2744 CREATIVE_MODE_TABS .register (modEventBus );
2845 }
46+
47+ private record RegistrateDisplayItemsGenerator (boolean addItems , RegistryObject <CreativeModeTab > tabFilter ) implements CreativeModeTab .DisplayItemsGenerator {
48+ private static final Predicate <Item > IS_ITEM_3D_PREDICATE ;
49+
50+ static {
51+ MutableObject <Predicate <Item >> isItem3d = new MutableObject <>(item -> false );
52+ DistExecutor .unsafeRunWhenOn (Dist .CLIENT , () -> () -> {
53+ isItem3d .setValue (item -> {
54+ ItemRenderer itemRenderer = Minecraft .getInstance ()
55+ .getItemRenderer ();
56+ BakedModel model = itemRenderer .getModel (new ItemStack (item ), null , null , 0 );
57+ return model .isGui3d ();
58+ });
59+ });
60+ IS_ITEM_3D_PREDICATE = isItem3d .getValue ();
61+ }
62+
63+ private static Predicate <Item > makeExclusionPredicate () {
64+ Set <Item > exclusions = new ReferenceOpenHashSet <>();
65+
66+ List <ItemProviderEntry <?>> simpleExclusions = List .of (
67+ ItemRegistry .INCOMPLETE_CODE_DRONE ,
68+ ItemRegistry .INCOMPLETE_CLOCKCOPTER
69+ );
70+
71+ exclusions .addAll (simpleExclusions .stream ().map (ItemProviderEntry ::asItem ).toList ());
72+
73+ return exclusions ::contains ;
74+ }
75+
76+ private static List <ItemOrdering > makeOrderings () {
77+ List <ItemOrdering > orderings = new ReferenceArrayList <>();
78+
79+ Map <ItemProviderEntry <?>, ItemProviderEntry <?>> simpleBeforeOrderings = Map .of (
80+ );
81+
82+ Map <ItemProviderEntry <?>, ItemProviderEntry <?>> simpleAfterOrderings = Map .of (
83+ );
84+
85+ simpleBeforeOrderings .forEach ((entry , otherEntry ) -> {
86+ orderings .add (RegistrateDisplayItemsGenerator .ItemOrdering .before (entry .asItem (), otherEntry .asItem ()));
87+ });
88+
89+ simpleAfterOrderings .forEach ((entry , otherEntry ) -> {
90+ orderings .add (RegistrateDisplayItemsGenerator .ItemOrdering .after (entry .asItem (), otherEntry .asItem ()));
91+ });
92+
93+ return orderings ;
94+ }
95+
96+ private static Function <Item , ItemStack > makeStackFunc () {
97+ Map <Item , Function <Item , ItemStack >> factories = new Reference2ReferenceOpenHashMap <>();
98+
99+ Map <ItemProviderEntry <?>, Function <Item , ItemStack >> simpleFactories = Map .of (
100+ );
101+
102+ simpleFactories .forEach ((entry , factory ) -> {
103+ factories .put (entry .asItem (), factory );
104+ });
105+
106+ return item -> {
107+ Function <Item , ItemStack > factory = factories .get (item );
108+ if (factory != null ) {
109+ return factory .apply (item );
110+ }
111+ return new ItemStack (item );
112+ };
113+ }
114+
115+ private static Function <Item , CreativeModeTab .TabVisibility > makeVisibilityFunc () {
116+ Map <Item , CreativeModeTab .TabVisibility > visibilities = new Reference2ObjectOpenHashMap <>();
117+
118+ Map <ItemProviderEntry <?>, CreativeModeTab .TabVisibility > simpleVisibilities = Map .of (
119+ );
120+
121+ simpleVisibilities .forEach ((entry , factory ) -> {
122+ visibilities .put (entry .asItem (), factory );
123+ });
124+
125+ return item -> {
126+ CreativeModeTab .TabVisibility visibility = visibilities .get (item );
127+ if (visibility != null ) {
128+ return visibility ;
129+ }
130+ return CreativeModeTab .TabVisibility .PARENT_AND_SEARCH_TABS ;
131+ };
132+ }
133+
134+ @ Override
135+ public void accept (CreativeModeTab .ItemDisplayParameters parameters , CreativeModeTab .Output output ) {
136+ Predicate <Item > exclusionPredicate = makeExclusionPredicate ();
137+ List <ItemOrdering > orderings = makeOrderings ();
138+ Function <Item , ItemStack > stackFunc = makeStackFunc ();
139+ Function <Item , CreativeModeTab .TabVisibility > visibilityFunc = makeVisibilityFunc ();
140+
141+ List <Item > items = new LinkedList <>();
142+ if (this .addItems ) {
143+ items .addAll (this .collectItems (exclusionPredicate .or (IS_ITEM_3D_PREDICATE .negate ())));
144+ }
145+ items .addAll (this .collectBlocks (exclusionPredicate ));
146+ if (this .addItems ) {
147+ items .addAll (this .collectItems (exclusionPredicate .or (IS_ITEM_3D_PREDICATE )));
148+ }
149+
150+ applyOrderings (items , orderings );
151+ outputAll (output , items , stackFunc , visibilityFunc );
152+ }
153+
154+ private List <Item > collectBlocks (Predicate <Item > exclusionPredicate ) {
155+ List <Item > items = new ReferenceArrayList <>();
156+ for (RegistryEntry <Block > entry : Robotics .REGISTRATE .getAll (Registries .BLOCK )) {
157+ if (!CreateRegistrate .isInCreativeTab (entry , this .tabFilter ))
158+ continue ;
159+ Item item = entry .get ()
160+ .asItem ();
161+ if (item == Items .AIR )
162+ continue ;
163+ if (!exclusionPredicate .test (item ))
164+ items .add (item );
165+ }
166+ items = new ReferenceArrayList <>(new ReferenceLinkedOpenHashSet <>(items ));
167+ return items ;
168+ }
169+
170+ private List <Item > collectItems (Predicate <Item > exclusionPredicate ) {
171+ List <Item > items = new ReferenceArrayList <>();
172+ for (RegistryEntry <Item > entry : Robotics .REGISTRATE .getAll (Registries .ITEM )) {
173+ if (!CreateRegistrate .isInCreativeTab (entry , this .tabFilter ))
174+ continue ;
175+ Item item = entry .get ();
176+ if (item instanceof BlockItem )
177+ continue ;
178+ if (!exclusionPredicate .test (item ))
179+ items .add (item );
180+ }
181+ return items ;
182+ }
183+
184+ private static void applyOrderings (List <Item > items , List <ItemOrdering > orderings ) {
185+ for (RegistrateDisplayItemsGenerator .ItemOrdering ordering : orderings ) {
186+ int anchorIndex = items .indexOf (ordering .anchor ());
187+ if (anchorIndex != -1 ) {
188+ Item item = ordering .item ();
189+ int itemIndex = items .indexOf (item );
190+ if (itemIndex != -1 ) {
191+ items .remove (itemIndex );
192+ if (itemIndex < anchorIndex ) {
193+ anchorIndex --;
194+ }
195+ }
196+ if (ordering .type () == RegistrateDisplayItemsGenerator .ItemOrdering .Type .AFTER ) {
197+ items .add (anchorIndex + 1 , item );
198+ } else {
199+ items .add (anchorIndex , item );
200+ }
201+ }
202+ }
203+ }
204+
205+ private static void outputAll (CreativeModeTab .Output output , List <Item > items , Function <Item , ItemStack > stackFunc , Function <Item , CreativeModeTab .TabVisibility > visibilityFunc ) {
206+ for (Item item : items ) {
207+ output .accept (stackFunc .apply (item ), visibilityFunc .apply (item ));
208+ }
209+ }
210+
211+ private record ItemOrdering (Item item , Item anchor , RegistrateDisplayItemsGenerator .ItemOrdering .Type type ) {
212+ public static RegistrateDisplayItemsGenerator .ItemOrdering before (Item item , Item anchor ) {
213+ return new RegistrateDisplayItemsGenerator .ItemOrdering (item , anchor ,
214+ RegistrateDisplayItemsGenerator .ItemOrdering .Type .BEFORE );
215+ }
216+
217+ public static RegistrateDisplayItemsGenerator .ItemOrdering after (Item item , Item anchor ) {
218+ return new RegistrateDisplayItemsGenerator .ItemOrdering (item , anchor ,
219+ RegistrateDisplayItemsGenerator .ItemOrdering .Type .AFTER );
220+ }
221+
222+ public enum Type {
223+ BEFORE ,
224+ AFTER
225+ }
226+ }
227+ }
29228}
0 commit comments