1212
1313import com .mojang .blaze3d .vertex .PoseStack ;
1414import net .minecraft .core .BlockPos ;
15+ import net .minecraft .world .entity .Entity ;
16+ import net .minecraft .world .level .block .BaseEntityBlock ;
17+ import net .minecraft .world .level .block .ButtonBlock ;
18+ import net .minecraft .world .level .block .CraftingTableBlock ;
19+ import net .minecraft .world .level .block .DoorBlock ;
20+ import net .minecraft .world .level .block .FenceGateBlock ;
21+ import net .minecraft .world .level .block .LeverBlock ;
22+ import net .minecraft .world .level .block .PressurePlateBlock ;
23+ import net .minecraft .world .level .block .TrapDoorBlock ;
1524import net .minecraft .world .level .block .state .BlockState ;
1625import net .minecraft .world .phys .AABB ;
1726import net .minecraft .world .phys .Vec3 ;
@@ -35,6 +44,11 @@ public final class MeasurementEspHack extends Hack implements RenderListener
3544 private final CheckboxSetting lockWhileFreecam =
3645 new CheckboxSetting ("Lock while Freecam" ,
3746 "Keep the last target when Freecam is enabled." , true );
47+ private final CheckboxSetting blockMode = new CheckboxSetting ("Block mode" ,
48+ "Use the current block-based color scheme." , true );
49+ private final CheckboxSetting reachMode = new CheckboxSetting ("Reach mode" ,
50+ "Use reach-based colors (white default, red on entities, yellow on interactive blocks). Overrides Block mode." ,
51+ false );
3852 private final ButtonSetting markButton =
3953 new ButtonSetting ("Mark current" , this ::markCurrent );
4054 private final ButtonSetting clearButton =
@@ -48,6 +62,8 @@ public MeasurementEspHack()
4862 super ("MeasurementESP" );
4963 addSetting (distance );
5064 addSetting (lockWhileFreecam );
65+ addSetting (blockMode );
66+ addSetting (reachMode );
5167 addSetting (markButton );
5268 addSetting (clearButton );
5369 }
@@ -70,6 +86,11 @@ public void onRender(PoseStack matrixStack, float partialTicks)
7086 if (MC == null || MC .level == null || MC .player == null )
7187 return ;
7288
89+ boolean useReachMode = reachMode .isChecked ();
90+ boolean useBlockMode = blockMode .isChecked ();
91+ if (!useReachMode && !useBlockMode )
92+ return ;
93+
7394 boolean freecam = WURST .getHax ().freecamHack .isEnabled ();
7495 Vec3 target ;
7596 if (freecam && lockWhileFreecam .isChecked () && lastPos != null )
@@ -89,71 +110,109 @@ public void onRender(PoseStack matrixStack, float partialTicks)
89110
90111 int lineColor ;
91112 int fillColor ;
113+ AABB box ;
92114
93- boolean isAir = state .isAir ();
94- boolean aboveAir = false ;
95- try
96- {
97- BlockState above = MC .level .getBlockState (pos .above ());
98- aboveAir = above .isAir ();
99- }catch (Throwable ignored )
100- {}
101-
102- if (isAir && aboveAir )
115+ if (useReachMode )
103116 {
104- lineColor = 0xFF00FF00 ;
105- fillColor = 0x4000FF00 ;
106- }else if (isAir )
107- {
108- lineColor = 0xFFFFFF00 ;
109- fillColor = 0x40FFFF00 ;
117+ ReachVisual reach = getReachVisuals (pos );
118+ lineColor = reach .lineColor ;
119+ fillColor = reach .fillColor ;
120+ box = reach .box ;
110121 }else
111122 {
112- lineColor = 0xFFFF0000 ;
113- fillColor = 0x40FF0000 ;
123+ BlockColors colors = getBlockModeColors (pos , state );
124+ lineColor = colors .lineColor ;
125+ fillColor = colors .fillColor ;
126+ box = new AABB (pos .getX (), pos .getY (), pos .getZ (), pos .getX () + 1.0 ,
127+ pos .getY () + 1.0 , pos .getZ () + 1.0 );
114128 }
115129
116- AABB box = new AABB (pos .getX (), pos .getY (), pos .getZ (),
117- pos .getX () + 1.0 , pos .getY () + 1.0 , pos .getZ () + 1.0 );
118-
119130 boolean depthTest = NiceWurstModule .enforceDepthTest (false );
120131 RenderUtils .drawSolidBox (matrixStack , box , fillColor , depthTest );
121132 RenderUtils .drawOutlinedBox (matrixStack , box , lineColor , depthTest );
122133
123134 for (BlockPos mpos : marked )
124135 {
125136 BlockState mstate = MC .level .getBlockState (mpos );
126- boolean misAir = mstate .isAir ();
127- boolean maboveAir = false ;
128- try
129- {
130- maboveAir = MC .level .getBlockState (mpos .above ()).isAir ();
131- }catch (Throwable ignored )
132- {}
133-
134- int mline ;
135- int mfill ;
136- if (misAir && maboveAir )
137- {
138- mline = 0xFF00FF00 ;
139- mfill = 0x4000FF00 ;
140- }else if (misAir )
141- {
142- mline = 0xFFFFFF00 ;
143- mfill = 0x40FFFF00 ;
144- }else
145- {
146- mline = 0xFFFF0000 ;
147- mfill = 0x40FF0000 ;
148- }
137+ BlockColors mcolors = useReachMode ? getReachBlockColors (mstate )
138+ : getBlockModeColors (mpos , mstate );
149139
150140 AABB mb = new AABB (mpos .getX (), mpos .getY (), mpos .getZ (),
151141 mpos .getX () + 1.0 , mpos .getY () + 1.0 , mpos .getZ () + 1.0 );
152- RenderUtils .drawSolidBox (matrixStack , mb , mfill , depthTest );
153- RenderUtils .drawOutlinedBox (matrixStack , mb , mline , depthTest );
142+ RenderUtils .drawSolidBox (matrixStack , mb , mcolors .fillColor ,
143+ depthTest );
144+ RenderUtils .drawOutlinedBox (matrixStack , mb , mcolors .lineColor ,
145+ depthTest );
154146 }
155147 }
156148
149+ private BlockColors getBlockModeColors (BlockPos pos , BlockState state )
150+ {
151+ boolean isAir = state .isAir ();
152+ boolean aboveAir = false ;
153+ try
154+ {
155+ BlockState above = MC .level .getBlockState (pos .above ());
156+ aboveAir = above .isAir ();
157+ }catch (Throwable ignored )
158+ {}
159+
160+ if (isAir && aboveAir )
161+ return new BlockColors (0xFF00FF00 , 0x4000FF00 );
162+
163+ if (isAir )
164+ return new BlockColors (0xFFFFFF00 , 0x40FFFF00 );
165+
166+ return new BlockColors (0xFFFF0000 , 0x40FF0000 );
167+ }
168+
169+ private ReachVisual getReachVisuals (BlockPos fallbackPos )
170+ {
171+ AABB box = new AABB (fallbackPos .getX (), fallbackPos .getY (),
172+ fallbackPos .getZ (), fallbackPos .getX () + 1.0 ,
173+ fallbackPos .getY () + 1.0 , fallbackPos .getZ () + 1.0 );
174+
175+ if (hasEntityAt (box ))
176+ return new ReachVisual (box , 0xFFFF0000 , 0x20FF0000 );
177+
178+ BlockState state = MC .level .getBlockState (fallbackPos );
179+ BlockColors colors = getReachBlockColors (state );
180+ return new ReachVisual (box , colors .lineColor , colors .fillColor );
181+ }
182+
183+ private BlockColors getReachBlockColors (BlockState state )
184+ {
185+ if (isReachInteractive (state ))
186+ return new BlockColors (0xFFFFFF00 , 0x20FFFF00 );
187+
188+ return new BlockColors (0xFFFFFFFF , 0x20FFFFFF );
189+ }
190+
191+ private boolean isReachInteractive (BlockState state )
192+ {
193+ return state .getBlock () instanceof BaseEntityBlock
194+ || state .getBlock () instanceof CraftingTableBlock
195+ || state .getBlock () instanceof DoorBlock
196+ || state .getBlock () instanceof TrapDoorBlock
197+ || state .getBlock () instanceof FenceGateBlock
198+ || state .getBlock () instanceof ButtonBlock
199+ || state .getBlock () instanceof LeverBlock
200+ || state .getBlock () instanceof PressurePlateBlock ;
201+ }
202+
203+ private boolean hasEntityAt (AABB box )
204+ {
205+ List <Entity > entities =
206+ MC .level .getEntities (MC .player , box , Entity ::isAlive );
207+ return !entities .isEmpty ();
208+ }
209+
210+ private record BlockColors (int lineColor , int fillColor )
211+ {}
212+
213+ private record ReachVisual (AABB box , int lineColor , int fillColor )
214+ {}
215+
157216 public void setDistance (int value )
158217 {
159218 distance .setValue (value );
0 commit comments