From 378396439d80575239f52893500a9a8376896d94 Mon Sep 17 00:00:00 2001 From: LaoShui <3048087505@qq.com> Date: Tue, 9 Jul 2024 22:29:24 +0800 Subject: [PATCH] feat: ItemESP(NovoLine) Improved mixins json --- .../net/ccbluex/liquidbounce/event/Events.kt | 6 +- .../module/modules/render/ItemESP.java | 334 ++++++++++++++++++ .../features/module/modules/render/ItemESP.kt | 68 ---- .../liquidbounce/utils/RenderUtil.java | 138 ++++---- .../liquidbounce/utils/render/ScaleUtils.java | 62 ++++ src/main/resources/mixins.fdpclient.json | 1 - 6 files changed, 462 insertions(+), 147 deletions(-) create mode 100644 src/main/java/net/ccbluex/liquidbounce/features/module/modules/render/ItemESP.java delete mode 100644 src/main/java/net/ccbluex/liquidbounce/features/module/modules/render/ItemESP.kt create mode 100644 src/main/java/net/ccbluex/liquidbounce/utils/render/ScaleUtils.java diff --git a/src/main/java/net/ccbluex/liquidbounce/event/Events.kt b/src/main/java/net/ccbluex/liquidbounce/event/Events.kt index b1aa466ae..48275b0e3 100644 --- a/src/main/java/net/ccbluex/liquidbounce/event/Events.kt +++ b/src/main/java/net/ccbluex/liquidbounce/event/Events.kt @@ -131,7 +131,11 @@ class PushOutEvent : CancellableEvent() /** * Called when screen is going to be rendered */ -class Render2DEvent(val partialTicks: Float, val scaledResolution: ScaledResolution) : Event() +class Render2DEvent(val partialTicks: Float, val scaledResolution: ScaledResolution) : Event() { + fun getResolution(): ScaledResolution { + return this.scaledResolution + } +} /** * Called when world is going to be rendered diff --git a/src/main/java/net/ccbluex/liquidbounce/features/module/modules/render/ItemESP.java b/src/main/java/net/ccbluex/liquidbounce/features/module/modules/render/ItemESP.java new file mode 100644 index 000000000..a2bbcc94e --- /dev/null +++ b/src/main/java/net/ccbluex/liquidbounce/features/module/modules/render/ItemESP.java @@ -0,0 +1,334 @@ +/* + * FDPClient Hacked Client + * A free open source mixin-based injection hacked client for Minecraft using Minecraft Forge by LiquidBounce. + * https://github.com/UnlegitMinecraft/FDPClientChina/ + */ +package net.ccbluex.liquidbounce.features.module.modules.render; + +import net.ccbluex.liquidbounce.event.EventTarget; +import net.ccbluex.liquidbounce.event.Render2DEvent; +import net.ccbluex.liquidbounce.features.module.Module; +import net.ccbluex.liquidbounce.features.module.ModuleCategory; +import net.ccbluex.liquidbounce.features.module.ModuleInfo; +import net.ccbluex.liquidbounce.utils.RenderUtil; +import net.ccbluex.liquidbounce.utils.render.ScaleUtils; +import net.ccbluex.liquidbounce.value.BoolValue; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.resources.model.IBakedModel; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.Slot; +import net.minecraft.item.*; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.MathHelper; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.glu.GLU; + +import javax.vecmath.Vector3d; +import javax.vecmath.Vector4d; +import java.awt.*; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.Arrays; +import java.util.List; + +import static java.awt.Color.BLACK; +import static net.minecraft.enchantment.Enchantment.*; +import static net.minecraft.enchantment.EnchantmentHelper.getEnchantmentLevel; +import static net.minecraft.init.Items.skull; +import static net.minecraft.util.EnumChatFormatting.*; + +@ModuleInfo(name = "ItemESP", category = ModuleCategory.RENDER) +public class ItemESP extends Module { + + public BoolValue names = new BoolValue("Names", true); + private final IntBuffer viewport = GLAllocation.createDirectIntBuffer(16); + private final FloatBuffer modelView = GLAllocation.createDirectFloatBuffer(16); + private final FloatBuffer projection = GLAllocation.createDirectFloatBuffer(16); + private final FloatBuffer vector = GLAllocation.createDirectFloatBuffer(4); + + @EventTarget + public void onRender(Render2DEvent er) { + for (Entity o : mc.theWorld.getLoadedEntityList()) { + if (o instanceof EntityItem) { + IBakedModel ibakedmodel = mc.getRenderItem().getItemModelMesher().getItemModel(((EntityItem) o).getEntityItem()); + float f1 = MathHelper.sin(((float) ((EntityItem) o).getAge() + er.getPartialTicks()) / 10.0F + ((EntityItem) o).hoverStart) * 0.1F + 0.1F; + float f2 = ibakedmodel.getItemCameraTransforms().getTransform(ItemCameraTransforms.TransformType.GROUND).scale.y; + final double x = RenderUtil.interpolate(o.posX, o.lastTickPosX, er.getPartialTicks()), // @off + y = RenderUtil.interpolate(o.posY + f1, o.lastTickPosY + f1, er.getPartialTicks()), + z = RenderUtil.interpolate(o.posZ, o.lastTickPosZ, er.getPartialTicks()), + width = o.width / 1.4, + height = o.height + 0.2; // @on + + AxisAlignedBB aabb = new AxisAlignedBB(x - width, y, z - width, x + width, y + height, z + width); + List vectors = Arrays.asList(new Vector3d(aabb.minX, aabb.minY, aabb.minZ), + new Vector3d(aabb.minX, aabb.maxY, aabb.minZ), new Vector3d(aabb.maxX, aabb.minY, aabb.minZ), + new Vector3d(aabb.maxX, aabb.maxY, aabb.minZ), new Vector3d(aabb.minX, aabb.minY, aabb.maxZ), + new Vector3d(aabb.minX, aabb.maxY, aabb.maxZ), new Vector3d(aabb.maxX, aabb.minY, aabb.maxZ), + new Vector3d(aabb.maxX, aabb.maxY, aabb.maxZ)); + + mc.entityRenderer.setupCameraTransform(er.getPartialTicks(), 0); + + Vector4d position = null; + + for (Vector3d vector : vectors) { + vector = project2D(er.getResolution(), vector.x - mc.getRenderManager().viewerPosX, + vector.y - mc.getRenderManager().viewerPosY, + vector.z - mc.getRenderManager().viewerPosZ); + + if (vector != null && vector.z >= 0.0 && vector.z < 1.0) { + if (position == null) { + position = new Vector4d(vector.x, vector.y, vector.z, 0.0); + } + + position.x = Math.min(vector.x, position.x); + position.y = Math.min(vector.y, position.y); + position.z = Math.max(vector.x, position.z); + position.w = Math.max(vector.y, position.w); + } + } + + mc.entityRenderer.setupOverlayRendering(); + + if (position != null) { + double posX = position.x, posY = position.y, endPosX = position.z, endPosY = position.w; + + // region BOX + RenderUtil.drawCornerBox(posX, posY, endPosX, endPosY, isItemSpecial((EntityItem) o) ? 4 : 3, BLACK); + RenderUtil.drawCornerBox(posX, posY, endPosX, endPosY, isItemSpecial((EntityItem) o) ? 2 : 1, getItemColor((EntityItem) o)); + // endregion + + // region name + if (names.get()) { + float amp = 1; + switch (mc.gameSettings.guiScale) { + case 0: + amp = 0.5F; + break; + case 1: + amp = 2.0F; + break; + case 3: + amp = 0.6666666666666667F; + } + + double[] positions = ScaleUtils.getScaledMouseCoordinates(mc, posX, posY); + double[] positionsEnd = ScaleUtils.getScaledMouseCoordinates(mc, endPosX, endPosY); + double[] scaledPositions = new double[]{positions[0] * 2, positions[1] * 2, positionsEnd[0] * 2, positionsEnd[1] * 2}; + + GL11.glPushMatrix(); + GL11.glScalef(0.5f * amp, 0.5f * amp, 0.5f * amp); + double _width = Math.abs(scaledPositions[2] - scaledPositions[0]); + float v = (float) (mc.fontRendererObj.FONT_HEIGHT * 2) - mc.fontRendererObj.FONT_HEIGHT / 2f; + + mc.fontRendererObj.drawStringWithShadow(((EntityItem) o).getEntityItem().getDisplayName(), + (float) (scaledPositions[0] + _width / 2 - + mc.fontRendererObj.getStringWidth(((EntityItem) o).getEntityItem().getDisplayName()) / 2), + (float) positionsEnd[1] * 2 + v, + getItemColor((EntityItem) o).brighter().getRGB()); + GL11.glPopMatrix(); + // endregion + } + } + } + } + } + + private boolean isItemSpecial(EntityItem o) { + boolean special = o.getEntityItem().getItem() instanceof ItemArmor || + o.getEntityItem().getItem() == skull // + && !o.getEntityItem().getDisplayName().equalsIgnoreCase("Zombie Head") // + && !o.getEntityItem().getDisplayName().equalsIgnoreCase("Creeper Head") // + && !o.getEntityItem().getDisplayName().equalsIgnoreCase("Skeleton Skull") // + && !o.getEntityItem().getDisplayName().equalsIgnoreCase("Wither Skeleton Skull") // + && !o.getEntityItem().getDisplayName().equalsIgnoreCase(GREEN + "Frog's Hat") + || o.getEntityItem().getItem() instanceof ItemAppleGold; + + + if (o.getEntityItem().getItem() instanceof ItemArmor) { + + for (int type = 1; type < 5; type++) { + String strType = ""; + + switch (type) { + case 1: + strType = "helmet"; + break; + case 2: + strType = "chestplate"; + break; + case 3: + strType = "leggings"; + break; + case 4: + strType = "boots"; + break; + } + + + if (getSlotFromPlayerContainer(4 + type).getHasStack()) { + ItemStack is = getSlotFromPlayerContainer(4 + type).getStack(); + if (is.getItem().getUnlocalizedName().contains(strType) && o.getEntityItem().getItem().getUnlocalizedName().contains(strType)) { + return getProtection(o.getEntityItem()) > getProtection(getSlotFromPlayerContainer(4 + type).getStack()); + } + } + } + return !hasItem(o.getEntityItem()); + } else if (o.getEntityItem().getItem() instanceof ItemPickaxe) { + for (int i = 9; i < 45; i++) { + if (getSlotFromPlayerContainer(i).getHasStack()) { + if (getSlotFromPlayerContainer(i).getStack().getItem() instanceof ItemPickaxe) { + return getToolEffect(o.getEntityItem()) > getToolEffect(getSlotFromPlayerContainer(i).getStack()); + } + } + } + return !hasItem(o.getEntityItem()); + } else if (o.getEntityItem().getItem() instanceof ItemSpade) { + for (int i = 9; i < 45; i++) { + if (getSlotFromPlayerContainer(i).getHasStack()) { + if (getSlotFromPlayerContainer(i).getStack().getItem() instanceof ItemSpade) { + return getToolEffect(o.getEntityItem()) > getToolEffect(getSlotFromPlayerContainer(i).getStack()); + } + } + } + return !hasItem(o.getEntityItem()); + } else if (o.getEntityItem().getItem() instanceof ItemAxe) { + for (int i = 9; i < 45; i++) { + if (getSlotFromPlayerContainer(i).getHasStack()) { + if (getSlotFromPlayerContainer(i).getStack().getItem() instanceof ItemAxe) { + return getToolEffect(o.getEntityItem()) > getToolEffect(getSlotFromPlayerContainer(i).getStack()); + } + } + } + return !hasItem(o.getEntityItem()); + } + return special; + } + + private float getProtection(ItemStack stack) { + float protection = 0; + + if (stack.getItem() instanceof ItemArmor) { + ItemArmor armor = (ItemArmor) stack.getItem(); + + protection += (float) (armor.damageReduceAmount + (100 - armor.damageReduceAmount) * getEnchantmentLevel(Enchantment.protection.effectId, stack) * 0.0075D); + protection += (float) (getEnchantmentLevel(blastProtection.effectId, stack) / 100d); + protection += (float) (getEnchantmentLevel(fireProtection.effectId, stack) / 100d); + protection += (float) (getEnchantmentLevel(thorns.effectId, stack) / 100d); + protection += (float) (getEnchantmentLevel(unbreaking.effectId, stack) / 50d); + protection += (float) (getEnchantmentLevel(projectileProtection.effectId, stack) / 100d); + } + + return protection; + } + + private float getToolEffect(ItemStack stack) { + final Item item = stack.getItem(); + + if (!(item instanceof ItemTool)) { + return 0; + } + + final String name = item.getUnlocalizedName(); + final ItemTool tool = (ItemTool) item; + float value; + + if (item instanceof ItemPickaxe) { + value = tool.getStrVsBlock(stack, Blocks.stone); + if (name.toLowerCase().contains("gold")) value -= 5; + } else if (item instanceof ItemSpade) { + value = tool.getStrVsBlock(stack, Blocks.dirt); + if (name.toLowerCase().contains("gold")) value -= 5; + } else if (item instanceof ItemAxe) { + value = tool.getStrVsBlock(stack, Blocks.log); + if (name.toLowerCase().contains("gold")) value -= 5; + } else return 1f; + + value += (float) (EnchantmentHelper.getEnchantmentLevel(Enchantment.efficiency.effectId, stack) * 0.0075D); + value += (float) (EnchantmentHelper.getEnchantmentLevel(Enchantment.unbreaking.effectId, stack) / 100.0D); + + return value; + } + + + private boolean hasItem(ItemStack is) { + for (int i = 0; i < 3; i++) { + if (mc.thePlayer.inventory.armorInventory[i] != null) { + if (mc.thePlayer.inventory.armorInventory[i].getItem() == is.getItem()) { + return true; + } + } + } + for (int i = 9; i < 45; i++) { + if (getSlotFromPlayerContainer(i).getHasStack()) { + final ItemStack is1 = getSlotFromPlayerContainer(i).getStack(); + if (is.getItem() == is1.getItem()) { + return true; + } + } + } + return false; + } + + + private Color getItemColor(EntityItem o) { + + String displayName = o.getEntityItem().getDisplayName(); + if (displayName.equalsIgnoreCase(GOLD + "Excalibur") || displayName.equalsIgnoreCase("aDragon Sword") + || displayName.equalsIgnoreCase(GREEN + "Cornucopia") + || displayName.equalsIgnoreCase(RED + "Bloodlust") || displayName.equalsIgnoreCase(RED + "Artemis' Bow") + || displayName.equalsIgnoreCase(GREEN + "Miner's Blessing") || displayName.equalsIgnoreCase(GOLD + "Axe of Perun") + || displayName.equalsIgnoreCase(GOLD + "Cornucopia")) { + + return new Color(0xFF8A8AFF); + } + + if (!isItemSpecial(o)) { + return new Color(255, 255, 255); + } + + if (o.getEntityItem().getItem() instanceof ItemArmor) { + return new Color(75, 189, 193); + } else if (o.getEntityItem().getItem() instanceof ItemAppleGold) { + return new Color(255, 199, 71); + } else if (o.getEntityItem().getItem() instanceof ItemSkull && isItemSpecial(o)) { + return new Color(255, 199, 71); + } else if (o.getEntityItem().getItem() instanceof ItemSword) { + return new Color(255, 117, 117); + } else if (o.getEntityItem().getItem() instanceof ItemPickaxe) { + return new Color(130, 219, 82); + } else if (o.getEntityItem().getItem() instanceof ItemSpade) { + return new Color(130, 219, 82); + } else if (o.getEntityItem().getItem() instanceof ItemAxe) { + return new Color(130, 219, 82); + } else if (o.getEntityItem().getItem() instanceof ItemRecord) { + return new Color(255, 117, 117); + } else { + return new Color(255, 255, 255); + } + } + + private Vector3d project2D(ScaledResolution scaledResolution, double x, double y, double z) { + GL11.glGetFloat(2982, this.modelView); + GL11.glGetFloat(2983, this.projection); + GL11.glGetInteger(2978, this.viewport); + + if (GLU.gluProject((float) x, (float) y, (float) z, this.modelView, this.projection, this.viewport, + this.vector)) { + return new Vector3d(this.vector.get(0) / scaledResolution.getScaleFactor(), + (Display.getHeight() - this.vector.get(1)) / scaledResolution.getScaleFactor(), this.vector.get(2)); + } + + return null; + } + + public Slot getSlotFromPlayerContainer(int slot) { + return mc.thePlayer.inventoryContainer.getSlot(slot); + } +} diff --git a/src/main/java/net/ccbluex/liquidbounce/features/module/modules/render/ItemESP.kt b/src/main/java/net/ccbluex/liquidbounce/features/module/modules/render/ItemESP.kt deleted file mode 100644 index dcd9c4981..000000000 --- a/src/main/java/net/ccbluex/liquidbounce/features/module/modules/render/ItemESP.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * FDPClient Hacked Client - * A free open source mixin-based injection hacked client for Minecraft using Minecraft Forge by LiquidBounce. - * https://github.com/UnlegitMinecraft/FDPClientChina/ - */ -package net.ccbluex.liquidbounce.features.module.modules.render - -import net.ccbluex.liquidbounce.event.EventTarget -import net.ccbluex.liquidbounce.event.Render2DEvent -import net.ccbluex.liquidbounce.event.Render3DEvent -import net.ccbluex.liquidbounce.features.module.Module -import net.ccbluex.liquidbounce.features.module.ModuleCategory -import net.ccbluex.liquidbounce.features.module.ModuleInfo -import net.ccbluex.liquidbounce.utils.render.ColorUtils.rainbow -import net.ccbluex.liquidbounce.utils.render.RenderUtils -import net.ccbluex.liquidbounce.utils.render.shader.shaders.GlowShader -import net.ccbluex.liquidbounce.utils.render.shader.shaders.OutlineShader -import net.ccbluex.liquidbounce.value.BoolValue -import net.ccbluex.liquidbounce.value.FloatValue -import net.ccbluex.liquidbounce.value.IntegerValue -import net.ccbluex.liquidbounce.value.ListValue -import net.minecraft.entity.item.EntityItem -import net.minecraft.entity.projectile.EntityArrow -import java.awt.Color - -@ModuleInfo(name = "ItemESP", category = ModuleCategory.RENDER) -class ItemESP : Module() { - private val modeValue = - ListValue("Mode", arrayOf("Box", "OtherBox", "Outline", "ShaderOutline", "ShaderGlow"), "Box") - private val outlineWidth = FloatValue("Outline-Width", 3f, 0.5f, 5f).displayable { modeValue.equals("Outline") } - private val colorRedValue = IntegerValue("R", 0, 0, 255).displayable { !colorRainbowValue.get() } - private val colorGreenValue = IntegerValue("G", 255, 0, 255).displayable { !colorRainbowValue.get() } - private val colorBlueValue = IntegerValue("B", 0, 0, 255).displayable { !colorRainbowValue.get() } - private val colorRainbowValue = BoolValue("Rainbow", true) - - private fun getColor(): Color { - return if (colorRainbowValue.get()) rainbow() else Color(colorRedValue.get(), colorGreenValue.get(), colorBlueValue.get()) - } - - @EventTarget - fun onRender3D(event: Render3DEvent?) { - val color = getColor() - for (entity in mc.theWorld.loadedEntityList) { - if (!(entity is EntityItem || entity is EntityArrow)) continue - when (modeValue.get().lowercase()) { - "box" -> RenderUtils.drawEntityBox(entity, color, true, true, outlineWidth.get()) - "otherbox" -> RenderUtils.drawEntityBox(entity, color, false, true, outlineWidth.get()) - "outline" -> RenderUtils.drawEntityBox(entity, color, true, false, outlineWidth.get()) - } - } - } - - @EventTarget - fun onRender2D(event: Render2DEvent) { - val shader = (if (modeValue.equals("shaderoutline")) OutlineShader.OUTLINE_SHADER else if (modeValue.equals("shaderglow")) GlowShader.GLOW_SHADER else null) - ?: return - val partialTicks = event.partialTicks - - shader.startDraw(partialTicks) - - for (entity in mc.theWorld.loadedEntityList) { - if (!(entity is EntityItem || entity is EntityArrow)) continue - mc.renderManager.renderEntityStatic(entity, event.partialTicks, true) - } - - shader.stopDraw(getColor(), outlineWidth.get(), 1f) - } -} \ No newline at end of file diff --git a/src/main/java/net/ccbluex/liquidbounce/utils/RenderUtil.java b/src/main/java/net/ccbluex/liquidbounce/utils/RenderUtil.java index 58c8a1145..cb59e7f23 100644 --- a/src/main/java/net/ccbluex/liquidbounce/utils/RenderUtil.java +++ b/src/main/java/net/ccbluex/liquidbounce/utils/RenderUtil.java @@ -32,6 +32,8 @@ import java.nio.IntBuffer; import java.util.Random; +import static net.minecraft.client.renderer.GlStateManager.disableBlend; +import static net.minecraft.client.renderer.GlStateManager.enableTexture2D; import static org.lwjgl.opengl.GL11.*; public class RenderUtil { @@ -41,6 +43,10 @@ public static double interpolate(double newPos, double oldPos) { return oldPos + (newPos - oldPos) * Minecraft.getMinecraft().timer.renderPartialTicks; } + public static double interpolate(double current, double old, double scale) { + return old + (current - old) * scale; + } + public static void pre() { GL11.glDisable(2929); GL11.glDisable(3553); @@ -2091,88 +2097,66 @@ public static void drawExeterCrossESP(EntityLivingBase entity, int rgb, double x GlStateManager.popMatrix(); } - /** - * 在LWJGL中渲染AWT图形 - * @param shape 准备渲染的图形 - * @param epsilon 图形精细度,传0不做处理 - */ - /*public static void drawAWTShape(Shape shape, double epsilon) { - PathIterator path=shape.getPathIterator(new AffineTransform()); - Double[] cp=new Double[2]; // 记录上次操作的点用于计算曲线 + public static void drawCornerBox(double x, double y, double x2, double y2, double lw, Color color) { + double width = Math.abs(x2 - x); + double height = Math.abs(y2 - y); + double halfWidth = width / 4; + double halfHeight = height / 4; + start2D(); + GL11.glPushMatrix(); + GL11.glLineWidth((float) lw); + setColor(color); - GLUtessellator tess = GLU.gluNewTess(); // 创建GLUtessellator用于渲染凹多边形(GL_POLYGON只能渲染凸多边形) + GL11.glBegin(GL_LINE_STRIP); + GL11.glVertex2d(x + halfWidth, y); + GL11.glVertex2d(x, y); + GL11.glVertex2d(x, y + halfHeight); + GL11.glEnd(); - tess.gluTessCallback(GLU.GLU_TESS_BEGIN, TessCallback.INSTANCE); - tess.gluTessCallback(GLU.GLU_TESS_END, TessCallback.INSTANCE); - tess.gluTessCallback(GLU.GLU_TESS_VERTEX, TessCallback.INSTANCE); - tess.gluTessCallback(GLU.GLU_TESS_COMBINE, TessCallback.INSTANCE); - switch (path.getWindingRule()){ - case PathIterator.WIND_EVEN_ODD:{ - tess.gluTessProperty(GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_ODD); - break; - } - case PathIterator.WIND_NON_ZERO:{ - tess.gluTessProperty(GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_NONZERO); - break; - } - } + GL11.glBegin(GL_LINE_STRIP); + GL11.glVertex2d(x, y + height - halfHeight); + GL11.glVertex2d(x, y + height); + GL11.glVertex2d(x + halfWidth, y + height); + GL11.glEnd(); - // 缓存单个图形路径上的点用于精简以提升性能 - ArrayList pointsCache = new ArrayList<>(); - - tess.gluTessBeginPolygon(null); - - while (!path.isDone()){ - double[] segment=new double[6]; - int type=path.currentSegment(segment); - switch (type){ - case PathIterator.SEG_MOVETO:{ - tess.gluTessBeginContour(); - pointsCache.add(new Double[] {segment[0], segment[1]}); - cp[0] = segment[0]; - cp[1] = segment[1]; - break; - } - case PathIterator.SEG_LINETO:{ - pointsCache.add(new Double[] {segment[0], segment[1]}); - cp[0] = segment[0]; - cp[1] = segment[1]; - break; - } - case PathIterator.SEG_QUADTO:{ - Double[][] points=MathUtils.getPointsOnCurve(new Double[][]{new Double[]{cp[0], cp[1]}, new Double[]{segment[0], segment[1]}, new Double[]{segment[2], segment[3]}}, 10); - pointsCache.addAll(Arrays.asList(points)); - cp[0] = segment[2]; - cp[1] = segment[3]; - break; - } - case PathIterator.SEG_CUBICTO:{ - Double[][] points=MathUtils.getPointsOnCurve(new Double[][]{new Double[]{cp[0], cp[1]}, new Double[]{segment[0], segment[1]}, new Double[]{segment[2], segment[3]}, new Double[]{segment[4], segment[5]}}, 10); - pointsCache.addAll(Arrays.asList(points)); - cp[0] = segment[4]; - cp[1] = segment[5]; - break; - } - case PathIterator.SEG_CLOSE:{ - // 精简路径上的点 - for(Double[] point : MathUtils.simplifyPoints(pointsCache.toArray(new Double[0][0]), epsilon)){ - tessVertex(tess, new double[] {point[0], point[1], 0.0, 0.0, 0.0, 0.0}); - } - // 清除缓存以便画下一个图形 - pointsCache.clear(); - tess.gluTessEndContour(); - break; - } - } - path.next(); - } + GL11.glBegin(GL_LINE_STRIP); + GL11.glVertex2d(x + width - halfWidth, y + height); + GL11.glVertex2d(x + width, y + height); + GL11.glVertex2d(x + width, y + height - halfHeight); + GL11.glEnd(); + + GL11.glBegin(GL_LINE_STRIP); + GL11.glVertex2d(x + width, y + halfHeight); + GL11.glVertex2d(x + width, y); + GL11.glVertex2d(x + width - halfWidth, y); + GL11.glEnd(); - tess.gluEndPolygon(); - tess.gluDeleteTess(); + GL11.glPopMatrix(); + stop2D(); } - public static void tessVertex(GLUtessellator tessellator, double[] coords) { - tessellator.gluTessVertex(coords, 0, new VertexData(coords)); - }*/ + public static void start2D() { + glEnable(3042); + glDisable(3553); + glBlendFunc(770, 771); + glEnable(2848); + } + + public static void stop2D() { + glEnable(3553); + glDisable(3042); + glDisable(2848); + enableTexture2D(); + disableBlend(); + glColor4f(1, 1, 1, 1); + } + + public static void setColor(Color color) { + float alpha = (color.getRGB() >> 24 & 0xFF) / 255.0F; + float red = (color.getRGB() >> 16 & 0xFF) / 255.0F; + float green = (color.getRGB() >> 8 & 0xFF) / 255.0F; + float blue = (color.getRGB() & 0xFF) / 255.0F; + GL11.glColor4f(red, green, blue, alpha); + } } \ No newline at end of file diff --git a/src/main/java/net/ccbluex/liquidbounce/utils/render/ScaleUtils.java b/src/main/java/net/ccbluex/liquidbounce/utils/render/ScaleUtils.java new file mode 100644 index 000000000..a83859de8 --- /dev/null +++ b/src/main/java/net/ccbluex/liquidbounce/utils/render/ScaleUtils.java @@ -0,0 +1,62 @@ +package net.ccbluex.liquidbounce.utils.render; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; + +public class ScaleUtils { + + public static int[] getScaledMouseCoordinates(Minecraft mc, int mouseX, int mouseY){ + int x = mouseX; + int y = mouseY; + switch (mc.gameSettings.guiScale){ + case 0: + x*=2; + y*=2; + break; + case 1: + x*=0.5; + y*=0.5; + break; + case 3: + x*=1.4999999999999999998; + y*=1.4999999999999999998; + } + return new int[]{x,y}; + } + + + public static double[] getScaledMouseCoordinates(Minecraft mc, double mouseX, double mouseY){ + double x = mouseX; + double y = mouseY; + switch (mc.gameSettings.guiScale){ + case 0: + x*=2; + y*=2; + break; + case 1: + x*=0.5; + y*=0.5; + break; + case 3: + x*=1.4999999999999999998; + y*=1.4999999999999999998; + } + return new double[]{x,y}; + } + + + public static void scale(Minecraft mc){ + switch (mc.gameSettings.guiScale){ + case 0: + GlStateManager.scale(0.5,0.5,0.5); + break; + case 1: + GlStateManager.scale(2,2,2); + break; + case 3: + GlStateManager.scale(0.6666666666666667,0.6666666666666667,0.6666666666666667); + + } + } + +} diff --git a/src/main/resources/mixins.fdpclient.json b/src/main/resources/mixins.fdpclient.json index f395405a1..6d72abe15 100644 --- a/src/main/resources/mixins.fdpclient.json +++ b/src/main/resources/mixins.fdpclient.json @@ -1,6 +1,5 @@ { "required": true, - "minVersion": "0.7.11", "package": "net.ccbluex.liquidbounce.injection.forge.mixins", "refmap": "mixins.fdpclient.refmap.json", "compatibilityLevel": "JAVA_8",