World and Overlay Drawing
This example draws a glowing box, a vertical line and a nametag at a
configurable world position, plus a small HUD panel in the top-left corner of
the screen. It uses only the version-independent plugin API, so the exact same
source compiles and runs on 1.8.9, 1.18.2, 1.20.4 and 1.21.
It demonstrates:
- Subscribing to
RenderTickEventand switching onevent.type. - World drawing (
drawWorldBox,drawBlockBox,drawWorldLine,drawWorldNameTag) during theWORLDrender tick. - Overlay drawing (
drawOverlayFilledRect,drawOverlayRect,drawOverlayLine,drawOverlayText) during theOVERLAYrender tick. - Plugin settings (
Boolean,Coords,FloatSlider) controlling the drawing.
Entry point
import com.originmint.managers.PluginManager;
import com.originmint.plugin.IPlugin;
import com.originmint.plugin.settings.Boolean;
import com.originmint.plugin.settings.Coords;
import com.originmint.plugin.settings.FloatSlider;
public class DrawExample implements IPlugin {
final Boolean drawWorld = new Boolean("draw.world", "Draw world shapes", "Draw the box, line and nametag", true);
final Boolean drawOverlay = new Boolean("draw.overlay", "Draw overlay panel", "Draw the HUD panel", true);
final Boolean throughWalls = new Boolean("draw.through_walls", "Through walls", "Draw world shapes through terrain", true);
final Coords anchor = new Coords("draw.anchor", "Anchor position", "World position to draw around", 0, 100, 0);
final FloatSlider lineWidth = new FloatSlider("draw.line_width", "Line width", "Line thickness in pixels", 0.5F, 8.0F, 2.0F);
private final DrawListener listener = new DrawListener(this);
@Override
public void onEnable() {
PluginManager.getInstance().PLUGIN_EVENT_BUS.register(listener);
}
@Override
public void onDisable() {
PluginManager.getInstance().PLUGIN_EVENT_BUS.unregister(listener);
}
}
Draw listener
import com.originmint.managers.RenderManager;
import com.originmint.plugin.eventbus.Subscribe;
import com.originmint.plugin.events.RenderTickEvent;
public class DrawListener {
private final DrawExample owner;
public DrawListener(DrawExample owner) {
this.owner = owner;
}
@Subscribe
public void onRenderTick(RenderTickEvent event) {
if (event.type == RenderTickEvent.Type.WORLD && owner.drawWorld.value) {
drawWorldShapes();
} else if (event.type == RenderTickEvent.Type.OVERLAY && owner.drawOverlay.value) {
drawOverlayPanel();
}
}
private void drawWorldShapes() {
RenderManager render = RenderManager.getInstance();
double x = owner.anchor.x;
double y = owner.anchor.y;
double z = owner.anchor.z;
float width = owner.lineWidth.value;
boolean walls = owner.throughWalls.value;
// 1x1x1 wireframe box on the anchor block
render.drawWorldBox(x, y, z, x + 1, y + 1, z + 1, 0.2F, 1.0F, 0.4F, 1.0F, width, walls);
// Same idea with the block helper two blocks up (ARGB color)
render.drawBlockBox(x, y + 2, z, 0xFF2ED1FF, width, walls);
// Line from the box to a point 5 blocks up
render.drawWorldLine(x + 0.5, y + 1, z + 0.5, x + 0.5, y + 6, z + 0.5, 1.0F, 0.8F, 0.1F, 1.0F, width, walls);
// Billboarded nametag above everything
render.drawWorldNameTag(x + 0.5, y + 7, z + 0.5, "DrawExample", "anchor", 1.0F, 1.0F, 1.0F, 1.0F, walls, true);
}
private void drawOverlayPanel() {
RenderManager render = RenderManager.getInstance();
float width = owner.lineWidth.value;
int screenW = render.getOverlayWidth();
int screenH = render.getOverlayHeight();
render.drawOverlayFilledRect(10, 10, 220, 50, 0.0F, 0.0F, 0.0F, 0.6F);
render.drawOverlayRect(10, 10, 220, 50, 0.2F, 1.0F, 0.4F, 1.0F, width);
render.drawOverlayText(18, 18, "DrawExample " + screenW + "x" + screenH, 1.0F, 1.0F, 1.0F, 1.0F, 16);
render.drawOverlayText(18, 38, "anchor " + owner.anchor.x + ", " + owner.anchor.y + ", " + owner.anchor.z, 0.8F, 0.8F, 0.8F, 1.0F, 14);
}
}
Drawing around entities
To outline entities instead of fixed positions, use the entity helpers — they
take a net.minecraft.entity.Entity (same class name on every version):
render.drawEntityBox(entity, 0x80FF0000); // box around the entity
render.drawEntityLine(entity, 0x8000FF00); // camera-to-entity line
render.drawTracerLine(entity, 0x800000FF); // tracer from screen bottom
How you obtain the Entity instance (iterating the world entity list, etc.)
depends on the Minecraft version your plugin targets, so it is not part of
this version-independent example.