Skip to content

Instantly share code, notes, and snippets.

@Cadiboo
Last active January 23, 2019 06:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cadiboo/7e46eb6e59d94c29d12dfdb087ea8b9f to your computer and use it in GitHub Desktop.
Save Cadiboo/7e46eb6e59d94c29d12dfdb087ea8b9f to your computer and use it in GitHub Desktop.
Renders a trail of iron ore behind the render view entity
package io.github.cadiboo.testmod.client;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import java.util.ArrayList;
import static io.github.cadiboo.testmod.util.ModReference.MOD_ID;
import static net.minecraftforge.fml.relauncher.Side.CLIENT;
import static org.lwjgl.opengl.GL11.GL_QUADS;
/**
* Subscribe to events that should be handled on the PHYSICAL CLIENT in this class
*
* @author Cadiboo
*/
@Mod.EventBusSubscriber(modid = MOD_ID, value = CLIENT)
public final class ClientEventSubscriber {
private static final ArrayList<BlockPos> previousPositions = new ArrayList<>();
@SubscribeEvent
public static void onClientTickEvent(final TickEvent.ClientTickEvent event) {
if (Minecraft.getMinecraft().getRenderViewEntity() == null) {
return;
}
previousPositions.add(Minecraft.getMinecraft().getRenderViewEntity().getPosition());
while (previousPositions.size() > 25) {
previousPositions.remove(0);
}
}
@SubscribeEvent
public static void onRenderWorldLastEvent(final RenderWorldLastEvent event) {
if (previousPositions.isEmpty()) {
return;
}
final float partialTicks = event.getPartialTicks();
// Not always the player, is sometimes the mob the player is spectating. Mods that hijack the camera also often do it this way.
final Minecraft minecraft = Minecraft.getMinecraft();
final Entity renderViewEntity = minecraft.getRenderViewEntity();
assert renderViewEntity != null;
// Interpolating everything back to (0, 0, 0). You can find these transforms in the RenderEntity class
final double d0 = renderViewEntity.lastTickPosX + ((renderViewEntity.posX - renderViewEntity.lastTickPosX) * partialTicks);
final double d1 = renderViewEntity.lastTickPosY + ((renderViewEntity.posY - renderViewEntity.lastTickPosY) * partialTicks);
final double d2 = renderViewEntity.lastTickPosZ + ((renderViewEntity.posZ - renderViewEntity.lastTickPosZ) * partialTicks);
final Tessellator tessellator = Tessellator.getInstance();
final BufferBuilder bufferBuilder = tessellator.getBuffer();
// Transform to BlockPos (0, 0, 0)
bufferBuilder.setTranslation(-d0, -d1, -d2);
// Begin drawing quads in the block format
bufferBuilder.begin(GL_QUADS, DefaultVertexFormats.BLOCK);
final BlockRendererDispatcher blockRendererDispatcher = minecraft.getBlockRendererDispatcher();
final IBlockState state = Blocks.IRON_ORE.getDefaultState();
// Read-only access to the world
final IBlockAccess blockAccess = minecraft.world;
for (final BlockPos previousPosition : previousPositions) {
// Render the block with the dispatcher
blockRendererDispatcher.renderBlock(state, previousPosition, blockAccess, bufferBuilder);
}
// Draw with the tessellator, not the bufferBuilder
tessellator.draw();
// Reset translation
bufferBuilder.setTranslation(0, 0, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment