package slimeknights.tconstruct.tools.common.client;
import com.google.common.collect.ImmutableList;
import net.minecraft.block.Block;
import net.minecraft.block.BlockChest;
import net.minecraft.block.BlockEnderChest;
import net.minecraft.block.BlockSign;
import net.minecraft.block.BlockSkull;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.PlayerControllerMP;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.event.FOVUpdateEvent;
import net.minecraftforge.client.event.RenderSpecificHandEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.opengl.GL11;
import java.util.List;
import javax.annotation.Nonnull;
import slimeknights.tconstruct.library.tools.DualToolHarvestUtils;
import slimeknights.tconstruct.library.tools.IAoeTool;
import slimeknights.tconstruct.tools.ranged.TinkerRangedWeapons;
@SideOnly(Side.CLIENT)
public class RenderEvents implements IResourceManagerReloadListener {
private static final ResourceLocation widgetsTexPath = new ResourceLocation("textures/gui/widgets.png"); // GuiIngame.widgetsTexPath
private final TextureAtlasSprite[] destroyBlockIcons = new TextureAtlasSprite[10];
@SubscribeEvent
public void renderExtraBlockBreak(RenderWorldLastEvent event) {
PlayerControllerMP controllerMP = Minecraft.getMinecraft().playerController;
EntityPlayer player = Minecraft.getMinecraft().player;
World world = player.getEntityWorld();
ItemStack tool = player.getHeldItemMainhand();
// AOE preview
if(tool != null) {
Entity renderEntity = Minecraft.getMinecraft().getRenderViewEntity();
double distance = controllerMP.getBlockReachDistance();
RayTraceResult mop = renderEntity.rayTrace(distance, event.getPartialTicks());
if(mop != null) {
tool = DualToolHarvestUtils.getItemstackToUse(player, world.getBlockState(mop.getBlockPos()));
if(tool.getItem() instanceof IAoeTool) {
ImmutableList<BlockPos> extraBlocks = ((IAoeTool) tool.getItem()).getAOEBlocks(tool, world, player, mop.getBlockPos());
for(BlockPos pos : extraBlocks) {
event.getContext().drawSelectionBox(player, new RayTraceResult(new Vec3d(0, 0, 0), null, pos), 0, event.getPartialTicks());
}
}
}
}
// extra-blockbreak animation
if(controllerMP.isHittingBlock) {
tool = DualToolHarvestUtils.getItemstackToUse(player, world.getBlockState(controllerMP.currentBlock));
if(tool != null && tool.getItem() instanceof IAoeTool && ((IAoeTool) tool.getItem()).isAoeHarvestTool()) {
BlockPos pos = controllerMP.currentBlock;
drawBlockDamageTexture(Tessellator.getInstance(),
Tessellator.getInstance().getBuffer(),
player,
event.getPartialTicks(),
world,
((IAoeTool) tool.getItem()).getAOEBlocks(tool, world, player, pos));
}
}
}
// RenderGlobal.drawBlockDamageTexture
public void drawBlockDamageTexture(Tessellator tessellatorIn, VertexBuffer vertexBuffer, Entity entityIn, float partialTicks, World world, List<BlockPos> blocks) {
double d0 = entityIn.lastTickPosX + (entityIn.posX - entityIn.lastTickPosX) * (double) partialTicks;
double d1 = entityIn.lastTickPosY + (entityIn.posY - entityIn.lastTickPosY) * (double) partialTicks;
double d2 = entityIn.lastTickPosZ + (entityIn.posZ - entityIn.lastTickPosZ) * (double) partialTicks;
TextureManager renderEngine = Minecraft.getMinecraft().renderEngine;
int progress = (int) (Minecraft.getMinecraft().playerController.curBlockDamageMP * 10f) - 1; // 0-10
if(progress < 0) {
return;
}
renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
//preRenderDamagedBlocks BEGIN
GlStateManager.tryBlendFuncSeparate(774, 768, 1, 0);
GlStateManager.enableBlend();
GlStateManager.color(1.0F, 1.0F, 1.0F, 0.5F);
GlStateManager.doPolygonOffset(-3.0F, -3.0F);
GlStateManager.enablePolygonOffset();
GlStateManager.alphaFunc(516, 0.1F);
GlStateManager.enableAlpha();
GlStateManager.pushMatrix();
//preRenderDamagedBlocks END
vertexBuffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
vertexBuffer.setTranslation(-d0, -d1, -d2);
vertexBuffer.noColor();
for(BlockPos blockpos : blocks) {
double d3 = (double) blockpos.getX() - d0;
double d4 = (double) blockpos.getY() - d1;
double d5 = (double) blockpos.getZ() - d2;
Block block = world.getBlockState(blockpos).getBlock();
TileEntity te = world.getTileEntity(blockpos);
boolean hasBreak = block instanceof BlockChest || block instanceof BlockEnderChest
|| block instanceof BlockSign || block instanceof BlockSkull;
if(!hasBreak) {
hasBreak = te != null && te.canRenderBreaking();
}
if(!hasBreak) {
IBlockState iblockstate = world.getBlockState(blockpos);
if(iblockstate.getBlock().getMaterial(iblockstate) != Material.AIR) {
TextureAtlasSprite textureatlassprite = this.destroyBlockIcons[progress];
BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
blockrendererdispatcher.renderBlockDamage(iblockstate, blockpos, textureatlassprite, world);
}
}
}
tessellatorIn.draw();
vertexBuffer.setTranslation(0.0D, 0.0D, 0.0D);
// postRenderDamagedBlocks BEGIN
GlStateManager.disableAlpha();
GlStateManager.doPolygonOffset(0.0F, 0.0F);
GlStateManager.disablePolygonOffset();
GlStateManager.enableAlpha();
GlStateManager.depthMask(true);
GlStateManager.popMatrix();
// postRenderDamagedBlocks END
}
@SubscribeEvent
public void handRenderEvent(RenderSpecificHandEvent event) {
EntityPlayer player = Minecraft.getMinecraft().player;
if(event.getHand() == EnumHand.OFF_HAND && player.isHandActive()) {
ItemStack stack = player.getActiveItemStack();
if(stack != null && stack.getItemUseAction() == EnumAction.BOW) {
event.setCanceled(true);
}
}
ItemStack mainStack = player.getHeldItemMainhand();
RayTraceResult rt = Minecraft.getMinecraft().objectMouseOver;
if(mainStack != null
&& rt != null
&& rt.typeOfHit == RayTraceResult.Type.BLOCK
&& DualToolHarvestUtils.shouldUseOffhand(player, rt.getBlockPos(), mainStack)) {
event.setCanceled(true);
EnumHand hand;
ItemStack itemStack;
if(event.getHand() == EnumHand.MAIN_HAND) {
hand = EnumHand.OFF_HAND;
itemStack = player.getHeldItemOffhand();
}
else {
hand = EnumHand.MAIN_HAND;
itemStack = player.getHeldItemMainhand();
}
ItemRenderer itemRenderer = Minecraft.getMinecraft().getItemRenderer();
itemRenderer.renderItemInFirstPerson(
Minecraft.getMinecraft().player,
event.getPartialTicks(),
event.getInterpolatedPitch(),
hand,
event.getSwingProgress(),
itemStack,
event.getEquipProgress());
}
}
@SubscribeEvent
public void onFovEvent(FOVUpdateEvent event) {
ItemStack stack = event.getEntity().getActiveItemStack();
if(stack != null) {
float zoom = 0f;
float progress = 0f;
if(stack.getItem() == TinkerRangedWeapons.longBow) {
zoom = 0.35f;
progress = TinkerRangedWeapons.longBow.getDrawbackProgress(stack, event.getEntity());
}
if(zoom > 0) {
event.setNewfov(1f - (progress * progress) * zoom);
}
}
}
@Override
public void onResourceManagerReload(@Nonnull IResourceManager resourceManager) {
TextureMap texturemap = Minecraft.getMinecraft().getTextureMapBlocks();
for(int i = 0; i < this.destroyBlockIcons.length; ++i) {
this.destroyBlockIcons[i] = texturemap.getAtlasSprite("minecraft:blocks/destroy_stage_" + i);
}
}
}