44import com .circulation .circulation_networks .container .CFNBaseContainer ;
55import com .circulation .circulation_networks .gui .component .base .Component ;
66import com .circulation .circulation_networks .gui .component .base .ComponentAtlas ;
7- import com .circulation .circulation_networks .gui .component .base .ComponentGuiContext ;
87import com .circulation .circulation_networks .gui .component .base .ComponentScreenController ;
98import com .circulation .circulation_networks .gui .component .base .RenderPhase ;
109//? if <1.20 {
1110import com .circulation .circulation_networks .packets .ContainerProgressBar ;
1211import it .unimi .dsi .fastutil .objects .ObjectArrayList ;
12+ import net .minecraft .client .Minecraft ;
1313import net .minecraft .client .gui .inventory .GuiContainer ;
1414import net .minecraft .client .renderer .GlStateManager ;
15+ import net .minecraft .client .renderer .OpenGlHelper ;
16+ import net .minecraft .client .renderer .RenderHelper ;
17+ import net .minecraft .inventory .Slot ;
18+ import net .minecraft .item .ItemStack ;
1519import net .minecraftforge .fml .relauncher .Side ;
1620import net .minecraftforge .fml .relauncher .SideOnly ;
1721import org .lwjgl .input .Mouse ;
22+ import org .lwjgl .opengl .GL11 ;
1823//?} else if <1.21 {
1924/*import net.minecraft.client.gui.GuiGraphics;
2025import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
3237*/ //?}
3338
3439import javax .annotation .Nonnull ;
40+ import javax .annotation .Nullable ;
3541//? if <1.20 {
3642import java .awt .Rectangle ;
3743import java .io .IOException ;
4652 * <p>Rendering layers (bottom → top):
4753 * <ol>
4854 * <li>Background texture — implement {@link #drawBG}.</li>
49- * <li>Slots & item stacks — handled automatically by the parent screen .</li>
55+ * <li>Component-owned slot and item rendering .</li>
5056 * <li>Foreground labels — implement {@link #drawFG}.</li>
5157 * <li>Component layer — all {@link Component} instances registered via
5258 * {@link #buildComponents}, sorted ascending by z-index.</li>
5359 * <li>Component tooltip — collected from the topmost hovered component.</li>
54- * <li>Slot tooltip — vanilla hover-text for inventory slots (rendered last).</li>
5560 * </ol>
5661 *
5762 * <p>Event routing: Mouse and key events are delivered to components in descending
6267@ SuppressWarnings ("unused" )
6368//? if <1.20 {
6469@ SideOnly (Side .CLIENT )
65- public abstract class CFNBaseGui <T extends CFNBaseContainer > extends GuiContainer implements ComponentGuiContext {
70+ public abstract class CFNBaseGui <T extends CFNBaseContainer > extends GuiContainer {
6671//?} else {
6772/*@OnlyIn(Dist.CLIENT)
6873public abstract class CFNBaseGui extends AbstractContainerScreen<CFNBaseContainer> implements ComponentGuiContext {
6974*/ //?}
7075
7176 protected final T container ;
77+ @ Nullable
78+ protected Slot hoveredSlot ;
7279
7380 private final ComponentScreenController componentController = new ComponentScreenController ();
7481
@@ -88,7 +95,6 @@ protected CFNBaseGui(@Nonnull T container) {
8895 }
8996 */ //?}
9097
91- @ Override
9298 public int getGuiLeft () {
9399 //? if <1.20 {
94100 return guiLeft ;
@@ -97,7 +103,6 @@ public int getGuiLeft() {
97103 */ //?}
98104 }
99105
100- @ Override
101106 public int getGuiTop () {
102107 //? if <1.20 {
103108 return guiTop ;
@@ -106,6 +111,14 @@ public int getGuiTop() {
106111 */ //?}
107112 }
108113
114+ public void setHoveredSlot (@ Nullable Slot hoveredSlot ) {
115+ this .hoveredSlot = hoveredSlot ;
116+ }
117+
118+ public boolean isTopComponent (Component component , int mouseX , int mouseY ) {
119+ return componentController .getTopComponentAt (mouseX , mouseY ) == component ;
120+ }
121+
109122 // -------------------------------------------------------------------------
110123 // Component registration
111124 // -------------------------------------------------------------------------
@@ -181,6 +194,57 @@ private void renderComponentTooltip(int mouseX, int mouseY) {
181194 */ //?}
182195 }
183196
197+ private void renderCarriedStack (int mouseX , int mouseY ) {
198+ ItemStack carried = Minecraft .getMinecraft ().player .inventory .getItemStack ();
199+ if (carried .isEmpty ()) return ;
200+
201+ float prevZLevel = this .itemRender .zLevel ;
202+ resetGuiRenderState ();
203+ GlStateManager .enableRescaleNormal ();
204+ OpenGlHelper .setLightmapTextureCoords (OpenGlHelper .lightmapTexUnit , 240.0F , 240.0F );
205+ GlStateManager .setActiveTexture (OpenGlHelper .defaultTexUnit );
206+ RenderHelper .enableGUIStandardItemLighting ();
207+ GlStateManager .pushMatrix ();
208+ GlStateManager .translate (0.0F , 0.0F , 200.0F );
209+ this .itemRender .zLevel = 200.0F ;
210+ this .itemRender .renderItemAndEffectIntoGUI (Minecraft .getMinecraft ().player , carried , mouseX - 8 , mouseY - 8 );
211+ this .itemRender .renderItemOverlayIntoGUI (this .fontRenderer , carried , mouseX - 8 , mouseY - 8 , null );
212+ this .itemRender .zLevel = prevZLevel ;
213+ GlStateManager .popMatrix ();
214+ resetGuiRenderState ();
215+ }
216+
217+ private void resetGuiRenderState () {
218+ RenderHelper .disableStandardItemLighting ();
219+ GlStateManager .disableLighting ();
220+ GlStateManager .disableDepth ();
221+ GlStateManager .disableRescaleNormal ();
222+ GlStateManager .depthMask (true );
223+ GlStateManager .enableAlpha ();
224+ GlStateManager .alphaFunc (GL11 .GL_GREATER , 0.1F );
225+ GlStateManager .enableBlend ();
226+ GlStateManager .tryBlendFuncSeparate (
227+ GL11 .GL_SRC_ALPHA ,
228+ GL11 .GL_ONE_MINUS_SRC_ALPHA ,
229+ GL11 .GL_ONE ,
230+ GL11 .GL_ZERO
231+ );
232+ GlStateManager .colorMask (true , true , true , true );
233+ GlStateManager .color (1.0F , 1.0F , 1.0F , 1.0F );
234+
235+ GlStateManager .setActiveTexture (OpenGlHelper .lightmapTexUnit );
236+ GlStateManager .enableTexture2D ();
237+ GlStateManager .matrixMode (GL11 .GL_TEXTURE );
238+ GlStateManager .loadIdentity ();
239+ GlStateManager .disableTexture2D ();
240+
241+ GlStateManager .setActiveTexture (OpenGlHelper .defaultTexUnit );
242+ GlStateManager .enableTexture2D ();
243+ GlStateManager .matrixMode (GL11 .GL_TEXTURE );
244+ GlStateManager .loadIdentity ();
245+ GlStateManager .matrixMode (GL11 .GL_MODELVIEW );
246+ }
247+
184248 //? if <1.20 {
185249 @ Override
186250 protected final void drawGuiContainerBackgroundLayer (float partialTicks , int mouseX , int mouseY ) {
@@ -199,13 +263,37 @@ protected final void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
199263 public void drawScreen (int mouseX , int mouseY , float partialTicks ) {
200264 this .drawDefaultBackground ();
201265 componentController .handleActiveDrag (mouseX , mouseY );
266+ this .hoveredSlot = null ;
267+ resetGuiRenderState ();
268+
269+ renderBGPhase (mouseX , mouseY , partialTicks );
202270 resetColor ();
271+ this .drawBG (this .guiLeft , this .guiTop , mouseX , mouseY );
272+
273+ resetGuiRenderState ();
274+
203275 componentController .renderPhase (RenderPhase .NORMAL , mouseX , mouseY , partialTicks );
204- super .drawScreen (mouseX , mouseY , partialTicks );
276+
277+ resetGuiRenderState ();
278+ resetColor ();
279+ this .drawFG (this .guiLeft , this .guiTop , mouseX , mouseY );
280+ RenderHelper .enableGUIStandardItemLighting ();
281+ net .minecraftforge .common .MinecraftForge .EVENT_BUS .post (new net .minecraftforge .client .event .GuiContainerEvent .DrawForeground (this , mouseX , mouseY ));
282+
283+ resetGuiRenderState ();
205284 resetColor ();
206285 componentController .renderPhase (RenderPhase .FOREGROUND , mouseX , mouseY , partialTicks );
286+ renderCarriedStack (mouseX , mouseY );
287+ resetGuiRenderState ();
207288 renderComponentTooltip (mouseX , mouseY );
208- this .renderHoveredToolTip (mouseX , mouseY );
289+ GlStateManager .enableLighting ();
290+ GlStateManager .enableDepth ();
291+ RenderHelper .enableStandardItemLighting ();
292+ }
293+
294+ @ Override
295+ public Slot getSlotUnderMouse () {
296+ return this .hoveredSlot ;
209297 }
210298
211299 @ Override
0 commit comments