Исходник ItemESP с уровнями предметов

Начинающий
Статус
Оффлайн
Регистрация
7 Янв 2023
Сообщения
88
Реакции[?]
0
Поинты[?]
0
Увидел какую-то тему с убогими ItemESP, решил вам слить свои, написано если что под fabric 1.16.5

Сама функция ItemESP


Код:
package me.funtimeutils.module.impl;

import com.google.common.eventbus.Subscribe;
import com.mojang.blaze3d.systems.RenderSystem;
import me.funtimeutils.FuntimeUtils;
import me.funtimeutils.event.impl.EventRender3D;
import me.funtimeutils.module.api.Module;
import me.funtimeutils.module.api.ModuleInfo;
import me.funtimeutils.util.ItemStorage;
import me.funtimeutils.util.items.item.ClientItem;
import me.funtimeutils.util.render.RenderUtils;
import net.minecraft.entity.ItemEntity;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.Vec3d;

@ModuleInfo(name = "ItemESP", description = "Показывает донатные предметы")
public class ItemESP extends Module {

    @Subscribe
    public void onRender3D(EventRender3D e) {
        for (ItemEntity item : ItemStorage.getInstance().getItemEntities()) {
            ClientItem clientItem = FuntimeUtils.getInstance().getItemList().getItem(item.getStack());

            if (clientItem == null)
                continue;

            Vec3d pos = item.getPos().subtract(RenderUtils.getInterpolationOffset(item)).add(0, item.getEyeHeight(item.getPose()) + 0.75, 0);
            Vec3d interpolationOffset = RenderUtils.getInterpolationOffset(mc.player);

            Vec3d playerPos = mc.player.getPos().subtract(interpolationOffset);

            double scale = Math.max(2, playerPos.distanceTo(pos) / 3.5);

            RenderSystem.disableDepthTest();
            RenderSystem.depthMask(false);

            LiteralText text = new LiteralText(Formatting.RED + clientItem.getName() + " x" + item.getStack().getCount());

            RenderUtils.drawText(text, pos.x, pos.y, pos.z, scale, true);

            RenderSystem.depthMask(true);
            RenderSystem.enableDepthTest();
        }
    }

}
ItemList, объявите его где-нибудь в вашем коде:


Код:
package me.funtimeutils.util.items;

import me.funtimeutils.util.ChatUtil;
import me.funtimeutils.util.items.item.ClientItem;
import me.funtimeutils.util.items.item.level.LevelItem;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static net.minecraft.entity.attribute.EntityAttributeModifier.Operation.ADDITION;
import static net.minecraft.entity.attribute.EntityAttributeModifier.Operation.MULTIPLY_BASE;
import static net.minecraft.entity.attribute.EntityAttributes.*;
import static net.minecraft.entity.attribute.EntityAttributes.GENERIC_ATTACK_DAMAGE;
import static net.minecraft.entity.effect.StatusEffects.*;
import static net.minecraft.entity.effect.StatusEffects.SPEED;
import static net.minecraft.item.Items.*;

public class ItemList {
    private final List<ClientItem> items = new ArrayList<>();

    ClientItem tripwireSphere = new ClientItem()
            .name("Отмычка к сферам")
            .addTooltips("Этой отмычкой можно", "Открыть хранилище", "С Сферами")
            .check((item, stack) -> stack.getItem() == TRIPWIRE_HOOK && item.containsAllTooltip(stack));

    ClientItem trapka = new ClientItem()
            .name("Трапка")
            .tag("trap")
            .check((item, stack) -> stack.getTag() != null && stack.hasTag() && stack.getTag().contains(item.getTag()));

    ClientItem ledyanka = new ClientItem()
            .name("Ледяная стрела")
            .addEffect(SLOWNESS, 50, 100)
            .addEffect(WEAKNESS, 0, 120)
            .check((item, stack) -> stack.getItem() == TIPPED_ARROW && item.containsAllEffects(stack));

    ClientItem netheriteIngot = new ClientItem()
            .name("Незеритовый слиток")
            .check((item, stack) -> stack.getItem() == NETHERITE_INGOT);

    ClientItem enchantedGoldenApple = new ClientItem()
            .name("Чарка")
            .check((item, stack) -> stack.getItem() == ENCHANTED_GOLDEN_APPLE);

    ClientItem potionKillera = new ClientItem().name("Зелье Киллера")
            .addEffect(STRENGTH, 3, 3600)
            .addEffect(RESISTANCE, 0, 3600)
            .check(ClientItem::containsAllEffects);

    ClientItem potionPobeditela = new ClientItem()
            .name("Зелье Победителя")
            .addEffect(HEALTH_BOOST, 1, 3600)
            .addEffect(RESISTANCE, 0, 1200)
            .addEffect(INVISIBILITY, 0, 18000)
            .addEffect(REGENERATION, 1, 1200)
            .check(ClientItem::containsAllEffects);

    ClientItem potionMedic = new ClientItem()
            .name("Зелье Медика")
            .addEffect(HEALTH_BOOST, 2, 900)
            .addEffect(REGENERATION, 2, 900)
            .check(ClientItem::containsAllEffects);

    ClientItem potionSernaya = new ClientItem()
            .name("Серная Кислота")
            .addEffect(POISON, 1, 1000)
            .addEffect(SLOWNESS, 3, 1800)
            .addEffect(WEAKNESS, 2, 1800)
            .addEffect(WITHER, 4, 600)
            .check(ClientItem::containsAllEffects);

    ClientItem potionAgent = new ClientItem()
            .name("Зелье Агента")
            .addEffect(INVISIBILITY, 1, 18000)
            .addEffect(FIRE_RESISTANCE, 0, 18000)
            .addEffect(SPEED, 2, 18000)
            .addEffect(HASTE, 0, 3500)
            .addEffect(STRENGTH, 2, 6000)
            .check(ClientItem::containsAllEffects);

    ClientItem potionOtrizhka = new ClientItem()
            .name("Зелье Отрыжки")
            .addEffect(BLINDNESS, 0, 200)
            .addEffect(GLOWING, 0, 3600)
            .addEffect(HUNGER, 10, 1800)
            .addEffect(SLOWNESS, 2, 3600)
            .addEffect(WITHER, 4, 600)
            .check(ClientItem::containsAllEffects);

    LevelItem sphereApollona = new LevelItem()
            .name("Сфера Аполлона")
            .lcheck((item, stack) -> {
                if (stack.getItem() != PLAYER_HEAD)
                    return -1;

                if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(3, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 2;
                else if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(4, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 3;

                return -1;
            });

    LevelItem sphereTitana = new LevelItem()
            .name("Сфера Титана")
            .lcheck((item, stack) -> {
                if (stack.getItem() != PLAYER_HEAD)
                    return -1;

                List<EntityAttribute> attributes = Arrays.asList(GENERIC_ARMOR, GENERIC_ARMOR_TOUGHNESS);
                List<EntityAttribute> attributes1 = Arrays.asList(GENERIC_ARMOR, GENERIC_ARMOR_TOUGHNESS, GENERIC_MOVEMENT_SPEED);

                if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1, ADDITION), fromValueOperation(1, ADDITION)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(attributes1, Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, false))
                    return 2;
                else if (item.containsAllAttributes(attributes1, Arrays.asList(fromValueOperation(3, ADDITION), fromValueOperation(3, ADDITION), fromValueOperation(-0.15, MULTIPLY_BASE)), stack, false))
                    return 3;

                return -1;
            });

    LevelItem talGarmonii = new LevelItem()
            .name("Талисман Гармонии")
            .lcheck((item, stack) -> {
                if (stack.getItem() != TOTEM_OF_UNDYING)
                    return -1;

                List<EntityAttribute> attributes = Arrays.asList(GENERIC_ARMOR, GENERIC_MAX_HEALTH, GENERIC_ATTACK_DAMAGE);

                if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1,ADDITION), fromValueOperation(1, ADDITION), fromValueOperation(1, ADDITION)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1.5, ADDITION), fromValueOperation(1.5, ADDITION), fromValueOperation(1.5, ADDITION)), stack, true))
                    return 2;
                else if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION)), stack, true))
                    return 3;

                return -1;
            });
    
    // Дальше если что можете сами добавлять предметы, которые вам нужны, например божья аура и т.д.

    public ItemList() {
        reload();
    }

    private EntityAttributeModifier fromValueOperation(double value, EntityAttributeModifier.Operation operation) {
        return new EntityAttributeModifier("aa", value, operation);
    }

    public ClientItem getItem(ItemStack stack) {
        assert stack.getTag() != null;

        for (ClientItem item : items) {
            if (item instanceof ClientItem) {
                if (!(item instanceof LevelItem)) {
                    if (item.getCheck() == null) {
                        ChatUtil.addMessage("Null Check: " + item.getName());
                        break;
                    }

                    if (item.getCheck().check(item, stack)) {
                        return item;
                    }
                } else {
                    LevelItem levelItem = (LevelItem) item;

                    if (levelItem.getLevelCheck() == null) {
                        ChatUtil.addMessage("Level Item Null Check " + levelItem.getName());
                        break;
                    }

                    if (levelItem.getLevelCheck().check(levelItem, stack) != -1)
                        return levelItem.withLevel(levelItem.getLevelCheck().check(levelItem, stack));
                }
            }
        }

        return null;
    }

    public void reload() {
        this.items.clear();

        items.addAll(Arrays.asList(potionKillera, potionPobeditela, potionMedic, potionSernaya, potionAgent, potionOtrizhka, sphereApollona, sphereTitana, talGarmonii, tripwireSphere, trapka, ledyanka, netheriteIngot, enchantedGoldenApple));
    }
}
ClientItem и Check к нему:


Код:
package me.funtimeutils.util.items.item;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import lombok.Getter;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.PotionUtil;
import net.minecraft.text.Text;

import java.util.*;

@Getter
public class ClientItem {
    private final List<String> containsTooltip = new ArrayList<>();
    private final Map<Enchantment, Integer> containsEnchantments = new HashMap<>();
    private final List<StatusEffectInstance> effects = new ArrayList<>();
    private String tag;
    protected Check check;
    private String name;

    /**
     * Аттрибуты
     */

    private final Multimap<EntityAttribute, EntityAttributeModifier> attributes = HashMultimap.create();

    public ClientItem name(String name) {
        this.name = name;
        return this;
    }

    public ClientItem check(Check check) {
        this.check = check;
        return this;
    }

    public ClientItem tag(String tag) {
        this.tag = tag;
        return this;
    }
    
    private void addTooltip(String component) {
        this.containsTooltip.add(component);
    }

    public ClientItem addTooltips(String... ss) {
        for (String s : ss)
            this.addTooltip(s);

        return this;
    }
    
    // Можете добавить свои зачары чтобы добавить например незеритовые поножи на защиту 4
    public ClientItem addEnchantment(Enchantment enc, int amp) {
        if (containsEnchantments.containsKey(enc))
            return this;

        this.containsEnchantments.put(enc, amp);
        return this;
    }

    public ClientItem addEffect(StatusEffect effect, int amp, int duration) {
        this.effects.add(new StatusEffectInstance(effect, duration, amp));
        return this;
    }

    public ClientItem addAttribute(EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        this.attributes.put(attribute, new EntityAttributeModifier(attribute.getTranslationKey(), value, operation));
        return this;
    }

    private boolean containsAttribute(EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        List<EntityAttributeModifier> matchingModifiers = new ArrayList<>();

        for (EntityAttribute attribute1 : attributes.keySet()) {
            if (attribute1 != attribute)
                continue;

            for (EntityAttributeModifier modifier : attributes.get(attribute))
                if (modifier.getOperation() == operation && modifier.getValue() == value)
                    matchingModifiers.add(modifier);
        }

        return !matchingModifiers.isEmpty();
    }

    public boolean containsAllAttributes(ItemStack stack) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = stack.getAttributeModifiers(EquipmentSlot.OFFHAND);

        if (attributes.size() != this.attributes.size())
            return false;

        for (Map.Entry<EntityAttribute, EntityAttributeModifier> entry : attributes.entries()) {
            EntityAttribute key = entry.getKey();
            EntityAttributeModifier value = entry.getValue();

            if (!containsAttribute(key, value.getValue(), value.getOperation())) {
                return false;
            }
        }

        return true;
    }

    public boolean containsAllEffects(ItemStack stack) {
        List<StatusEffectInstance> itemEffects = PotionUtil.getPotionEffects(stack);

        if (effects.size() != itemEffects.size())
            return false;

        for (StatusEffectInstance effect : effects) {
            boolean matchFound = false;

            for (StatusEffectInstance itemEffect : itemEffects) {
                if (itemEffect.getEffectType().equals(effect.getEffectType()) && itemEffect.getAmplifier() <= effect.getAmplifier()) {
                    matchFound = true;
                    break;
                }
            }

            if (!matchFound) {
                return false;
            }
        }

        return true;
    }

    // Чтобы чекать на наличие зачаров на броне
    public boolean containsAllEnchantments(ItemStack stack) {
        Map<Enchantment, Integer> enchantments = EnchantmentHelper.get(stack);
        
        for (Enchantment ench : this.containsEnchantments.keySet()) {
            int value = this.containsEnchantments.get(ench);

            if (!enchantments.containsKey(ench) || enchantments.get(ench) != value)
                return false;
        }

        return true;
    }

    public boolean containsAllTooltip(ItemStack stack) {
        List<Text> components = getTooltip(stack);

        for (String s : this.containsTooltip) {
            if (!contains(components, s))
                return false;
        }

        return true;
    }

    private List<Text> getTooltip(ItemStack stack) {
        final MinecraftClient mc = MinecraftClient.getInstance();

        return stack.getTooltip(mc.player, mc.options.advancedItemTooltips ? TooltipContext.Default.ADVANCED : TooltipContext.Default.NORMAL);
    }

    private boolean contains(List<Text> list, String found) {
        for (Text t : list)
            if (t.getString().contains(found))
                return true;

        return false;
    }
    
}
Код:
package me.funtimeutils.util.items.item;

import net.minecraft.item.ItemStack;

@FunctionalInterface
public interface Check {
    boolean check(ClientItem item, ItemStack stack);
}
LevelItem и Check к нему


Код:
package me.funtimeutils.util.items.item.level;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import lombok.Getter;
import lombok.Setter;
import me.funtimeutils.util.items.item.ClientItem;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Getter
@Setter
public class LevelItem extends ClientItem {
    private LevelCheck levelCheck;
    private int level;

    @Override
    public String getName() {
        return super.getName() + " " + (level == 3 ? "MAX" : level) + " уровня";
    }

    public LevelItem lcheck(LevelCheck check) {
        this.levelCheck = check;
        return this;
    }

    @Override
    public LevelItem name(String name) {
        super.name(name);
        return this;
    }

    public LevelItem withLevel(int level) {
        this.level = level;
        return this;
    }

    private boolean containsAttribute(Multimap<EntityAttribute, EntityAttributeModifier> attributes, EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        List<EntityAttributeModifier> matchingModifiers = new ArrayList<>();

        for (EntityAttribute attribute1 : attributes.keySet()) {
            if (attribute1 != attribute)
                continue;

            for (EntityAttributeModifier modifier : attributes.get(attribute))
                if (modifier.getOperation() == operation && modifier.getValue() == value)
                    matchingModifiers.add(modifier);
        }

        return !matchingModifiers.isEmpty();
    }

    public boolean containsAllAttributes(List<EntityAttribute> list, List<EntityAttributeModifier> modifiers, ItemStack stack, boolean withSize) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = stack.getAttributeModifiers(EquipmentSlot.OFFHAND);
        Multimap<EntityAttribute, EntityAttributeModifier> att = attributesFromLists(list, modifiers);

        if (att.isEmpty())
            return false;

        if (withSize && att.size() != attributes.size())
            return false;

        for (Map.Entry<EntityAttribute, EntityAttributeModifier> entry : att.entries()) {
            EntityAttribute key = entry.getKey();
            EntityAttributeModifier value = entry.getValue();

            if (!containsAttribute(attributes, key, value.getValue(), value.getOperation()))
                return false;
        }

        return true;
    }

    private Multimap<EntityAttribute, EntityAttributeModifier> attributesFromLists(List<EntityAttribute> list, List<EntityAttributeModifier> modifiers) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = HashMultimap.create();

        for (EntityAttribute attribute : list) {
            EntityAttributeModifier modifier = modifiers.get(list.indexOf(attribute));

            attributes.put(attribute, modifier);
        }

        return attributes;
    }
}

Код:
package me.funtimeutils.util.items.item.level;

import net.minecraft.item.ItemStack;

@FunctionalInterface
public interface LevelCheck {
    int check(LevelItem levelItem, ItemStack stack);
}
ItemStorage

Код:
package me.funtimeutils.util;

import com.google.common.eventbus.Subscribe;
import lombok.Getter;
import me.funtimeutils.event.impl.EventTick;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;

import java.util.ArrayList;
import java.util.List;

@Getter
public class ItemStorage {
    @Getter
    private static ItemStorage Instance;
    private final MinecraftClient mc = MinecraftClient.getInstance();
    private final List<ItemEntity> itemEntities = new ArrayList<>();

    public ItemStorage() {
        Instance = this;
    }

    @Subscribe
    public void onTick(EventTick e) {
        itemEntities.clear();

        assert mc.world != null;
        for (Entity entity : mc.world.getEntities()) {
            if (!(entity instanceof ItemEntity))
                continue;

            ItemEntity item = (ItemEntity) entity;

            itemEntities.add(item);
        }
    }

}

Мб кому-то нужен будет Mixin, чтобы понимать где происходит пост ивента EventRender3D


Код:
package me.funtimeutils.mixin;

import me.funtimeutils.FuntimeUtils;
import me.funtimeutils.event.impl.EventRender3D;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.LightmapTextureManager;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Matrix4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(WorldRenderer.class)
public class MixinWorldRenderer {

    @Unique
    EventRender3D eventRender3D;

    @Inject(at = @At("RETURN"), method = "render")
    private void render(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
        eventRender3D = new EventRender3D(matrices, tickDelta);
        FuntimeUtils.getInstance().getEventBus().post(eventRender3D);
    }

}
Все утилиты


Код:
    public static MatrixStack matrixFrom(double x, double y, double z) {
        MatrixStack matrices = new MatrixStack();

        Camera camera = mc.gameRenderer.getCamera();
        matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(camera.getPitch()));
        matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(camera.getYaw() + 180.0F));

        matrices.translate(x - camera.getPos().x, y - camera.getPos().y, z - camera.getPos().z);

        return matrices;
    }

    public Vec3d getInterpolationOffset(Entity e) {
        float tickDelta = mc.getTickDelta();

        double posX = e.getX() - MathHelper.lerp(tickDelta, e.prevX, e.getX());
        double posY = e.getY() - MathHelper.lerp(tickDelta, e.prevY, e.getY());
        double posZ = e.getZ() - MathHelper.lerp(tickDelta, e.prevZ, e.getZ());

        return new Vec3d(posX, posY, posZ);
    }

    public void drawText(Text text, double x, double y, double z, double scale, boolean shadow) {
        drawText(text, x, y, z, 0, 0, scale, shadow);
    }

    public void drawText(Text text, double x, double y, double z, double offX, double offY, double scale, boolean fill) {
        MatrixStack matrices = matrixFrom(x, y, z);

        Camera camera = mc.gameRenderer.getCamera();
        matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(-camera.getYaw()));
        matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(camera.getPitch()));

        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();

        matrices.translate(offX, offY, 0);
        matrices.scale(-0.025f * (float) scale, -0.025f * (float) scale, 1);

        int halfWidth = mc.textRenderer.getWidth(text.getString()) / 2;

        VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());

        if (fill) {
            int opacity = (int) (MinecraftClient.getInstance().options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24;
            mc.textRenderer.draw(text, -halfWidth, 0f, 553648127, false, matrices.peek().getModel(), immediate, true, opacity, 0xf000f0);
            immediate.draw();
        } else {
            matrices.push();
            matrices.translate(1, 1, 0);
            mc.textRenderer.draw(text.copy(), -halfWidth, 0f, 0x202020, false, matrices.peek().getModel(), immediate, true, 0, 0xf000f0);
            immediate.draw();
            matrices.pop();
        }

        mc.textRenderer.draw(text, -halfWidth, 0f, -1, false, matrices.peek().getModel(), immediate, true, 0, 0xf000f0);
        immediate.draw();

        RenderSystem.disableBlend();
    }
ss:

1724074448814.png
Удачи вам адаптировать всё это под mcp!
 
Начинающий
Статус
Оффлайн
Регистрация
12 Июн 2024
Сообщения
320
Реакции[?]
1
Поинты[?]
1K
Увидел какую-то тему с убогими ItemESP, решил вам слить свои, написано если что под fabric 1.16.5

Сама функция ItemESP


Код:
package me.funtimeutils.module.impl;

import com.google.common.eventbus.Subscribe;
import com.mojang.blaze3d.systems.RenderSystem;
import me.funtimeutils.FuntimeUtils;
import me.funtimeutils.event.impl.EventRender3D;
import me.funtimeutils.module.api.Module;
import me.funtimeutils.module.api.ModuleInfo;
import me.funtimeutils.util.ItemStorage;
import me.funtimeutils.util.items.item.ClientItem;
import me.funtimeutils.util.render.RenderUtils;
import net.minecraft.entity.ItemEntity;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.Vec3d;

@ModuleInfo(name = "ItemESP", description = "Показывает донатные предметы")
public class ItemESP extends Module {

    @Subscribe
    public void onRender3D(EventRender3D e) {
        for (ItemEntity item : ItemStorage.getInstance().getItemEntities()) {
            ClientItem clientItem = FuntimeUtils.getInstance().getItemList().getItem(item.getStack());

            if (clientItem == null)
                continue;

            Vec3d pos = item.getPos().subtract(RenderUtils.getInterpolationOffset(item)).add(0, item.getEyeHeight(item.getPose()) + 0.75, 0);
            Vec3d interpolationOffset = RenderUtils.getInterpolationOffset(mc.player);

            Vec3d playerPos = mc.player.getPos().subtract(interpolationOffset);

            double scale = Math.max(2, playerPos.distanceTo(pos) / 3.5);

            RenderSystem.disableDepthTest();
            RenderSystem.depthMask(false);

            LiteralText text = new LiteralText(Formatting.RED + clientItem.getName() + " x" + item.getStack().getCount());

            RenderUtils.drawText(text, pos.x, pos.y, pos.z, scale, true);

            RenderSystem.depthMask(true);
            RenderSystem.enableDepthTest();
        }
    }

}
ItemList, объявите его где-нибудь в вашем коде:


Код:
package me.funtimeutils.util.items;

import me.funtimeutils.util.ChatUtil;
import me.funtimeutils.util.items.item.ClientItem;
import me.funtimeutils.util.items.item.level.LevelItem;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static net.minecraft.entity.attribute.EntityAttributeModifier.Operation.ADDITION;
import static net.minecraft.entity.attribute.EntityAttributeModifier.Operation.MULTIPLY_BASE;
import static net.minecraft.entity.attribute.EntityAttributes.*;
import static net.minecraft.entity.attribute.EntityAttributes.GENERIC_ATTACK_DAMAGE;
import static net.minecraft.entity.effect.StatusEffects.*;
import static net.minecraft.entity.effect.StatusEffects.SPEED;
import static net.minecraft.item.Items.*;

public class ItemList {
    private final List<ClientItem> items = new ArrayList<>();

    ClientItem tripwireSphere = new ClientItem()
            .name("Отмычка к сферам")
            .addTooltips("Этой отмычкой можно", "Открыть хранилище", "С Сферами")
            .check((item, stack) -> stack.getItem() == TRIPWIRE_HOOK && item.containsAllTooltip(stack));

    ClientItem trapka = new ClientItem()
            .name("Трапка")
            .tag("trap")
            .check((item, stack) -> stack.getTag() != null && stack.hasTag() && stack.getTag().contains(item.getTag()));

    ClientItem ledyanka = new ClientItem()
            .name("Ледяная стрела")
            .addEffect(SLOWNESS, 50, 100)
            .addEffect(WEAKNESS, 0, 120)
            .check((item, stack) -> stack.getItem() == TIPPED_ARROW && item.containsAllEffects(stack));

    ClientItem netheriteIngot = new ClientItem()
            .name("Незеритовый слиток")
            .check((item, stack) -> stack.getItem() == NETHERITE_INGOT);

    ClientItem enchantedGoldenApple = new ClientItem()
            .name("Чарка")
            .check((item, stack) -> stack.getItem() == ENCHANTED_GOLDEN_APPLE);

    ClientItem potionKillera = new ClientItem().name("Зелье Киллера")
            .addEffect(STRENGTH, 3, 3600)
            .addEffect(RESISTANCE, 0, 3600)
            .check(ClientItem::containsAllEffects);

    ClientItem potionPobeditela = new ClientItem()
            .name("Зелье Победителя")
            .addEffect(HEALTH_BOOST, 1, 3600)
            .addEffect(RESISTANCE, 0, 1200)
            .addEffect(INVISIBILITY, 0, 18000)
            .addEffect(REGENERATION, 1, 1200)
            .check(ClientItem::containsAllEffects);

    ClientItem potionMedic = new ClientItem()
            .name("Зелье Медика")
            .addEffect(HEALTH_BOOST, 2, 900)
            .addEffect(REGENERATION, 2, 900)
            .check(ClientItem::containsAllEffects);

    ClientItem potionSernaya = new ClientItem()
            .name("Серная Кислота")
            .addEffect(POISON, 1, 1000)
            .addEffect(SLOWNESS, 3, 1800)
            .addEffect(WEAKNESS, 2, 1800)
            .addEffect(WITHER, 4, 600)
            .check(ClientItem::containsAllEffects);

    ClientItem potionAgent = new ClientItem()
            .name("Зелье Агента")
            .addEffect(INVISIBILITY, 1, 18000)
            .addEffect(FIRE_RESISTANCE, 0, 18000)
            .addEffect(SPEED, 2, 18000)
            .addEffect(HASTE, 0, 3500)
            .addEffect(STRENGTH, 2, 6000)
            .check(ClientItem::containsAllEffects);

    ClientItem potionOtrizhka = new ClientItem()
            .name("Зелье Отрыжки")
            .addEffect(BLINDNESS, 0, 200)
            .addEffect(GLOWING, 0, 3600)
            .addEffect(HUNGER, 10, 1800)
            .addEffect(SLOWNESS, 2, 3600)
            .addEffect(WITHER, 4, 600)
            .check(ClientItem::containsAllEffects);

    LevelItem sphereApollona = new LevelItem()
            .name("Сфера Аполлона")
            .lcheck((item, stack) -> {
                if (stack.getItem() != PLAYER_HEAD)
                    return -1;

                if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(3, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 2;
                else if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(4, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 3;

                return -1;
            });

    LevelItem sphereTitana = new LevelItem()
            .name("Сфера Титана")
            .lcheck((item, stack) -> {
                if (stack.getItem() != PLAYER_HEAD)
                    return -1;

                List<EntityAttribute> attributes = Arrays.asList(GENERIC_ARMOR, GENERIC_ARMOR_TOUGHNESS);
                List<EntityAttribute> attributes1 = Arrays.asList(GENERIC_ARMOR, GENERIC_ARMOR_TOUGHNESS, GENERIC_MOVEMENT_SPEED);

                if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1, ADDITION), fromValueOperation(1, ADDITION)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(attributes1, Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, false))
                    return 2;
                else if (item.containsAllAttributes(attributes1, Arrays.asList(fromValueOperation(3, ADDITION), fromValueOperation(3, ADDITION), fromValueOperation(-0.15, MULTIPLY_BASE)), stack, false))
                    return 3;

                return -1;
            });

    LevelItem talGarmonii = new LevelItem()
            .name("Талисман Гармонии")
            .lcheck((item, stack) -> {
                if (stack.getItem() != TOTEM_OF_UNDYING)
                    return -1;

                List<EntityAttribute> attributes = Arrays.asList(GENERIC_ARMOR, GENERIC_MAX_HEALTH, GENERIC_ATTACK_DAMAGE);

                if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1,ADDITION), fromValueOperation(1, ADDITION), fromValueOperation(1, ADDITION)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1.5, ADDITION), fromValueOperation(1.5, ADDITION), fromValueOperation(1.5, ADDITION)), stack, true))
                    return 2;
                else if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION)), stack, true))
                    return 3;

                return -1;
            });
   
    // Дальше если что можете сами добавлять предметы, которые вам нужны, например божья аура и т.д.

    public ItemList() {
        reload();
    }

    private EntityAttributeModifier fromValueOperation(double value, EntityAttributeModifier.Operation operation) {
        return new EntityAttributeModifier("aa", value, operation);
    }

    public ClientItem getItem(ItemStack stack) {
        assert stack.getTag() != null;

        for (ClientItem item : items) {
            if (item instanceof ClientItem) {
                if (!(item instanceof LevelItem)) {
                    if (item.getCheck() == null) {
                        ChatUtil.addMessage("Null Check: " + item.getName());
                        break;
                    }

                    if (item.getCheck().check(item, stack)) {
                        return item;
                    }
                } else {
                    LevelItem levelItem = (LevelItem) item;

                    if (levelItem.getLevelCheck() == null) {
                        ChatUtil.addMessage("Level Item Null Check " + levelItem.getName());
                        break;
                    }

                    if (levelItem.getLevelCheck().check(levelItem, stack) != -1)
                        return levelItem.withLevel(levelItem.getLevelCheck().check(levelItem, stack));
                }
            }
        }

        return null;
    }

    public void reload() {
        this.items.clear();

        items.addAll(Arrays.asList(potionKillera, potionPobeditela, potionMedic, potionSernaya, potionAgent, potionOtrizhka, sphereApollona, sphereTitana, talGarmonii, tripwireSphere, trapka, ledyanka, netheriteIngot, enchantedGoldenApple));
    }
}
ClientItem и Check к нему:


Код:
package me.funtimeutils.util.items.item;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import lombok.Getter;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.PotionUtil;
import net.minecraft.text.Text;

import java.util.*;

@Getter
public class ClientItem {
    private final List<String> containsTooltip = new ArrayList<>();
    private final Map<Enchantment, Integer> containsEnchantments = new HashMap<>();
    private final List<StatusEffectInstance> effects = new ArrayList<>();
    private String tag;
    protected Check check;
    private String name;

    /**
     * Аттрибуты
     */

    private final Multimap<EntityAttribute, EntityAttributeModifier> attributes = HashMultimap.create();

    public ClientItem name(String name) {
        this.name = name;
        return this;
    }

    public ClientItem check(Check check) {
        this.check = check;
        return this;
    }

    public ClientItem tag(String tag) {
        this.tag = tag;
        return this;
    }
   
    private void addTooltip(String component) {
        this.containsTooltip.add(component);
    }

    public ClientItem addTooltips(String... ss) {
        for (String s : ss)
            this.addTooltip(s);

        return this;
    }
   
    // Можете добавить свои зачары чтобы добавить например незеритовые поножи на защиту 4
    public ClientItem addEnchantment(Enchantment enc, int amp) {
        if (containsEnchantments.containsKey(enc))
            return this;

        this.containsEnchantments.put(enc, amp);
        return this;
    }

    public ClientItem addEffect(StatusEffect effect, int amp, int duration) {
        this.effects.add(new StatusEffectInstance(effect, duration, amp));
        return this;
    }

    public ClientItem addAttribute(EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        this.attributes.put(attribute, new EntityAttributeModifier(attribute.getTranslationKey(), value, operation));
        return this;
    }

    private boolean containsAttribute(EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        List<EntityAttributeModifier> matchingModifiers = new ArrayList<>();

        for (EntityAttribute attribute1 : attributes.keySet()) {
            if (attribute1 != attribute)
                continue;

            for (EntityAttributeModifier modifier : attributes.get(attribute))
                if (modifier.getOperation() == operation && modifier.getValue() == value)
                    matchingModifiers.add(modifier);
        }

        return !matchingModifiers.isEmpty();
    }

    public boolean containsAllAttributes(ItemStack stack) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = stack.getAttributeModifiers(EquipmentSlot.OFFHAND);

        if (attributes.size() != this.attributes.size())
            return false;

        for (Map.Entry<EntityAttribute, EntityAttributeModifier> entry : attributes.entries()) {
            EntityAttribute key = entry.getKey();
            EntityAttributeModifier value = entry.getValue();

            if (!containsAttribute(key, value.getValue(), value.getOperation())) {
                return false;
            }
        }

        return true;
    }

    public boolean containsAllEffects(ItemStack stack) {
        List<StatusEffectInstance> itemEffects = PotionUtil.getPotionEffects(stack);

        if (effects.size() != itemEffects.size())
            return false;

        for (StatusEffectInstance effect : effects) {
            boolean matchFound = false;

            for (StatusEffectInstance itemEffect : itemEffects) {
                if (itemEffect.getEffectType().equals(effect.getEffectType()) && itemEffect.getAmplifier() <= effect.getAmplifier()) {
                    matchFound = true;
                    break;
                }
            }

            if (!matchFound) {
                return false;
            }
        }

        return true;
    }

    // Чтобы чекать на наличие зачаров на броне
    public boolean containsAllEnchantments(ItemStack stack) {
        Map<Enchantment, Integer> enchantments = EnchantmentHelper.get(stack);
       
        for (Enchantment ench : this.containsEnchantments.keySet()) {
            int value = this.containsEnchantments.get(ench);

            if (!enchantments.containsKey(ench) || enchantments.get(ench) != value)
                return false;
        }

        return true;
    }

    public boolean containsAllTooltip(ItemStack stack) {
        List<Text> components = getTooltip(stack);

        for (String s : this.containsTooltip) {
            if (!contains(components, s))
                return false;
        }

        return true;
    }

    private List<Text> getTooltip(ItemStack stack) {
        final MinecraftClient mc = MinecraftClient.getInstance();

        return stack.getTooltip(mc.player, mc.options.advancedItemTooltips ? TooltipContext.Default.ADVANCED : TooltipContext.Default.NORMAL);
    }

    private boolean contains(List<Text> list, String found) {
        for (Text t : list)
            if (t.getString().contains(found))
                return true;

        return false;
    }
   
}
Код:
package me.funtimeutils.util.items.item;

import net.minecraft.item.ItemStack;

@FunctionalInterface
public interface Check {
    boolean check(ClientItem item, ItemStack stack);
}
LevelItem и Check к нему


Код:
package me.funtimeutils.util.items.item.level;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import lombok.Getter;
import lombok.Setter;
import me.funtimeutils.util.items.item.ClientItem;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Getter
@Setter
public class LevelItem extends ClientItem {
    private LevelCheck levelCheck;
    private int level;

    @Override
    public String getName() {
        return super.getName() + " " + (level == 3 ? "MAX" : level) + " уровня";
    }

    public LevelItem lcheck(LevelCheck check) {
        this.levelCheck = check;
        return this;
    }

    @Override
    public LevelItem name(String name) {
        super.name(name);
        return this;
    }

    public LevelItem withLevel(int level) {
        this.level = level;
        return this;
    }

    private boolean containsAttribute(Multimap<EntityAttribute, EntityAttributeModifier> attributes, EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        List<EntityAttributeModifier> matchingModifiers = new ArrayList<>();

        for (EntityAttribute attribute1 : attributes.keySet()) {
            if (attribute1 != attribute)
                continue;

            for (EntityAttributeModifier modifier : attributes.get(attribute))
                if (modifier.getOperation() == operation && modifier.getValue() == value)
                    matchingModifiers.add(modifier);
        }

        return !matchingModifiers.isEmpty();
    }

    public boolean containsAllAttributes(List<EntityAttribute> list, List<EntityAttributeModifier> modifiers, ItemStack stack, boolean withSize) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = stack.getAttributeModifiers(EquipmentSlot.OFFHAND);
        Multimap<EntityAttribute, EntityAttributeModifier> att = attributesFromLists(list, modifiers);

        if (att.isEmpty())
            return false;

        if (withSize && att.size() != attributes.size())
            return false;

        for (Map.Entry<EntityAttribute, EntityAttributeModifier> entry : att.entries()) {
            EntityAttribute key = entry.getKey();
            EntityAttributeModifier value = entry.getValue();

            if (!containsAttribute(attributes, key, value.getValue(), value.getOperation()))
                return false;
        }

        return true;
    }

    private Multimap<EntityAttribute, EntityAttributeModifier> attributesFromLists(List<EntityAttribute> list, List<EntityAttributeModifier> modifiers) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = HashMultimap.create();

        for (EntityAttribute attribute : list) {
            EntityAttributeModifier modifier = modifiers.get(list.indexOf(attribute));

            attributes.put(attribute, modifier);
        }

        return attributes;
    }
}

Код:
package me.funtimeutils.util.items.item.level;

import net.minecraft.item.ItemStack;

@FunctionalInterface
public interface LevelCheck {
    int check(LevelItem levelItem, ItemStack stack);
}
ItemStorage

Код:
package me.funtimeutils.util;

import com.google.common.eventbus.Subscribe;
import lombok.Getter;
import me.funtimeutils.event.impl.EventTick;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;

import java.util.ArrayList;
import java.util.List;

@Getter
public class ItemStorage {
    @Getter
    private static ItemStorage Instance;
    private final MinecraftClient mc = MinecraftClient.getInstance();
    private final List<ItemEntity> itemEntities = new ArrayList<>();

    public ItemStorage() {
        Instance = this;
    }

    @Subscribe
    public void onTick(EventTick e) {
        itemEntities.clear();

        assert mc.world != null;
        for (Entity entity : mc.world.getEntities()) {
            if (!(entity instanceof ItemEntity))
                continue;

            ItemEntity item = (ItemEntity) entity;

            itemEntities.add(item);
        }
    }

}

Мб кому-то нужен будет Mixin, чтобы понимать где происходит пост ивента EventRender3D


Код:
package me.funtimeutils.mixin;

import me.funtimeutils.FuntimeUtils;
import me.funtimeutils.event.impl.EventRender3D;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.LightmapTextureManager;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Matrix4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(WorldRenderer.class)
public class MixinWorldRenderer {

    @Unique
    EventRender3D eventRender3D;

    @Inject(at = @At("RETURN"), method = "render")
    private void render(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
        eventRender3D = new EventRender3D(matrices, tickDelta);
        FuntimeUtils.getInstance().getEventBus().post(eventRender3D);
    }

}
Все утилиты


Код:
    public static MatrixStack matrixFrom(double x, double y, double z) {
        MatrixStack matrices = new MatrixStack();

        Camera camera = mc.gameRenderer.getCamera();
        matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(camera.getPitch()));
        matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(camera.getYaw() + 180.0F));

        matrices.translate(x - camera.getPos().x, y - camera.getPos().y, z - camera.getPos().z);

        return matrices;
    }

    public Vec3d getInterpolationOffset(Entity e) {
        float tickDelta = mc.getTickDelta();

        double posX = e.getX() - MathHelper.lerp(tickDelta, e.prevX, e.getX());
        double posY = e.getY() - MathHelper.lerp(tickDelta, e.prevY, e.getY());
        double posZ = e.getZ() - MathHelper.lerp(tickDelta, e.prevZ, e.getZ());

        return new Vec3d(posX, posY, posZ);
    }

    public void drawText(Text text, double x, double y, double z, double scale, boolean shadow) {
        drawText(text, x, y, z, 0, 0, scale, shadow);
    }

    public void drawText(Text text, double x, double y, double z, double offX, double offY, double scale, boolean fill) {
        MatrixStack matrices = matrixFrom(x, y, z);

        Camera camera = mc.gameRenderer.getCamera();
        matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(-camera.getYaw()));
        matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(camera.getPitch()));

        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();

        matrices.translate(offX, offY, 0);
        matrices.scale(-0.025f * (float) scale, -0.025f * (float) scale, 1);

        int halfWidth = mc.textRenderer.getWidth(text.getString()) / 2;

        VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());

        if (fill) {
            int opacity = (int) (MinecraftClient.getInstance().options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24;
            mc.textRenderer.draw(text, -halfWidth, 0f, 553648127, false, matrices.peek().getModel(), immediate, true, opacity, 0xf000f0);
            immediate.draw();
        } else {
            matrices.push();
            matrices.translate(1, 1, 0);
            mc.textRenderer.draw(text.copy(), -halfWidth, 0f, 0x202020, false, matrices.peek().getModel(), immediate, true, 0, 0xf000f0);
            immediate.draw();
            matrices.pop();
        }

        mc.textRenderer.draw(text, -halfWidth, 0f, -1, false, matrices.peek().getModel(), immediate, true, 0, 0xf000f0);
        immediate.draw();

        RenderSystem.disableBlend();
    }
ss:

Посмотреть вложение 283688
Удачи вам адаптировать всё это под mcp!
для экспы 2.0 пойдет?
 
Начинающий
Статус
Оффлайн
Регистрация
6 Дек 2023
Сообщения
18
Реакции[?]
0
Поинты[?]
0
Увидел какую-то тему с убогими ItemESP, решил вам слить свои, написано если что под fabric 1.16.5

Сама функция ItemESP


Код:
package me.funtimeutils.module.impl;

import com.google.common.eventbus.Subscribe;
import com.mojang.blaze3d.systems.RenderSystem;
import me.funtimeutils.FuntimeUtils;
import me.funtimeutils.event.impl.EventRender3D;
import me.funtimeutils.module.api.Module;
import me.funtimeutils.module.api.ModuleInfo;
import me.funtimeutils.util.ItemStorage;
import me.funtimeutils.util.items.item.ClientItem;
import me.funtimeutils.util.render.RenderUtils;
import net.minecraft.entity.ItemEntity;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.Vec3d;

@ModuleInfo(name = "ItemESP", description = "Показывает донатные предметы")
public class ItemESP extends Module {

    @Subscribe
    public void onRender3D(EventRender3D e) {
        for (ItemEntity item : ItemStorage.getInstance().getItemEntities()) {
            ClientItem clientItem = FuntimeUtils.getInstance().getItemList().getItem(item.getStack());

            if (clientItem == null)
                continue;

            Vec3d pos = item.getPos().subtract(RenderUtils.getInterpolationOffset(item)).add(0, item.getEyeHeight(item.getPose()) + 0.75, 0);
            Vec3d interpolationOffset = RenderUtils.getInterpolationOffset(mc.player);

            Vec3d playerPos = mc.player.getPos().subtract(interpolationOffset);

            double scale = Math.max(2, playerPos.distanceTo(pos) / 3.5);

            RenderSystem.disableDepthTest();
            RenderSystem.depthMask(false);

            LiteralText text = new LiteralText(Formatting.RED + clientItem.getName() + " x" + item.getStack().getCount());

            RenderUtils.drawText(text, pos.x, pos.y, pos.z, scale, true);

            RenderSystem.depthMask(true);
            RenderSystem.enableDepthTest();
        }
    }

}
ItemList, объявите его где-нибудь в вашем коде:


Код:
package me.funtimeutils.util.items;

import me.funtimeutils.util.ChatUtil;
import me.funtimeutils.util.items.item.ClientItem;
import me.funtimeutils.util.items.item.level.LevelItem;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static net.minecraft.entity.attribute.EntityAttributeModifier.Operation.ADDITION;
import static net.minecraft.entity.attribute.EntityAttributeModifier.Operation.MULTIPLY_BASE;
import static net.minecraft.entity.attribute.EntityAttributes.*;
import static net.minecraft.entity.attribute.EntityAttributes.GENERIC_ATTACK_DAMAGE;
import static net.minecraft.entity.effect.StatusEffects.*;
import static net.minecraft.entity.effect.StatusEffects.SPEED;
import static net.minecraft.item.Items.*;

public class ItemList {
    private final List<ClientItem> items = new ArrayList<>();

    ClientItem tripwireSphere = new ClientItem()
            .name("Отмычка к сферам")
            .addTooltips("Этой отмычкой можно", "Открыть хранилище", "С Сферами")
            .check((item, stack) -> stack.getItem() == TRIPWIRE_HOOK && item.containsAllTooltip(stack));

    ClientItem trapka = new ClientItem()
            .name("Трапка")
            .tag("trap")
            .check((item, stack) -> stack.getTag() != null && stack.hasTag() && stack.getTag().contains(item.getTag()));

    ClientItem ledyanka = new ClientItem()
            .name("Ледяная стрела")
            .addEffect(SLOWNESS, 50, 100)
            .addEffect(WEAKNESS, 0, 120)
            .check((item, stack) -> stack.getItem() == TIPPED_ARROW && item.containsAllEffects(stack));

    ClientItem netheriteIngot = new ClientItem()
            .name("Незеритовый слиток")
            .check((item, stack) -> stack.getItem() == NETHERITE_INGOT);

    ClientItem enchantedGoldenApple = new ClientItem()
            .name("Чарка")
            .check((item, stack) -> stack.getItem() == ENCHANTED_GOLDEN_APPLE);

    ClientItem potionKillera = new ClientItem().name("Зелье Киллера")
            .addEffect(STRENGTH, 3, 3600)
            .addEffect(RESISTANCE, 0, 3600)
            .check(ClientItem::containsAllEffects);

    ClientItem potionPobeditela = new ClientItem()
            .name("Зелье Победителя")
            .addEffect(HEALTH_BOOST, 1, 3600)
            .addEffect(RESISTANCE, 0, 1200)
            .addEffect(INVISIBILITY, 0, 18000)
            .addEffect(REGENERATION, 1, 1200)
            .check(ClientItem::containsAllEffects);

    ClientItem potionMedic = new ClientItem()
            .name("Зелье Медика")
            .addEffect(HEALTH_BOOST, 2, 900)
            .addEffect(REGENERATION, 2, 900)
            .check(ClientItem::containsAllEffects);

    ClientItem potionSernaya = new ClientItem()
            .name("Серная Кислота")
            .addEffect(POISON, 1, 1000)
            .addEffect(SLOWNESS, 3, 1800)
            .addEffect(WEAKNESS, 2, 1800)
            .addEffect(WITHER, 4, 600)
            .check(ClientItem::containsAllEffects);

    ClientItem potionAgent = new ClientItem()
            .name("Зелье Агента")
            .addEffect(INVISIBILITY, 1, 18000)
            .addEffect(FIRE_RESISTANCE, 0, 18000)
            .addEffect(SPEED, 2, 18000)
            .addEffect(HASTE, 0, 3500)
            .addEffect(STRENGTH, 2, 6000)
            .check(ClientItem::containsAllEffects);

    ClientItem potionOtrizhka = new ClientItem()
            .name("Зелье Отрыжки")
            .addEffect(BLINDNESS, 0, 200)
            .addEffect(GLOWING, 0, 3600)
            .addEffect(HUNGER, 10, 1800)
            .addEffect(SLOWNESS, 2, 3600)
            .addEffect(WITHER, 4, 600)
            .check(ClientItem::containsAllEffects);

    LevelItem sphereApollona = new LevelItem()
            .name("Сфера Аполлона")
            .lcheck((item, stack) -> {
                if (stack.getItem() != PLAYER_HEAD)
                    return -1;

                if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(3, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 2;
                else if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(4, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 3;

                return -1;
            });

    LevelItem sphereTitana = new LevelItem()
            .name("Сфера Титана")
            .lcheck((item, stack) -> {
                if (stack.getItem() != PLAYER_HEAD)
                    return -1;

                List<EntityAttribute> attributes = Arrays.asList(GENERIC_ARMOR, GENERIC_ARMOR_TOUGHNESS);
                List<EntityAttribute> attributes1 = Arrays.asList(GENERIC_ARMOR, GENERIC_ARMOR_TOUGHNESS, GENERIC_MOVEMENT_SPEED);

                if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1, ADDITION), fromValueOperation(1, ADDITION)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(attributes1, Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, false))
                    return 2;
                else if (item.containsAllAttributes(attributes1, Arrays.asList(fromValueOperation(3, ADDITION), fromValueOperation(3, ADDITION), fromValueOperation(-0.15, MULTIPLY_BASE)), stack, false))
                    return 3;

                return -1;
            });

    LevelItem talGarmonii = new LevelItem()
            .name("Талисман Гармонии")
            .lcheck((item, stack) -> {
                if (stack.getItem() != TOTEM_OF_UNDYING)
                    return -1;

                List<EntityAttribute> attributes = Arrays.asList(GENERIC_ARMOR, GENERIC_MAX_HEALTH, GENERIC_ATTACK_DAMAGE);

                if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1,ADDITION), fromValueOperation(1, ADDITION), fromValueOperation(1, ADDITION)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1.5, ADDITION), fromValueOperation(1.5, ADDITION), fromValueOperation(1.5, ADDITION)), stack, true))
                    return 2;
                else if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION)), stack, true))
                    return 3;

                return -1;
            });
   
    // Дальше если что можете сами добавлять предметы, которые вам нужны, например божья аура и т.д.

    public ItemList() {
        reload();
    }

    private EntityAttributeModifier fromValueOperation(double value, EntityAttributeModifier.Operation operation) {
        return new EntityAttributeModifier("aa", value, operation);
    }

    public ClientItem getItem(ItemStack stack) {
        assert stack.getTag() != null;

        for (ClientItem item : items) {
            if (item instanceof ClientItem) {
                if (!(item instanceof LevelItem)) {
                    if (item.getCheck() == null) {
                        ChatUtil.addMessage("Null Check: " + item.getName());
                        break;
                    }

                    if (item.getCheck().check(item, stack)) {
                        return item;
                    }
                } else {
                    LevelItem levelItem = (LevelItem) item;

                    if (levelItem.getLevelCheck() == null) {
                        ChatUtil.addMessage("Level Item Null Check " + levelItem.getName());
                        break;
                    }

                    if (levelItem.getLevelCheck().check(levelItem, stack) != -1)
                        return levelItem.withLevel(levelItem.getLevelCheck().check(levelItem, stack));
                }
            }
        }

        return null;
    }

    public void reload() {
        this.items.clear();

        items.addAll(Arrays.asList(potionKillera, potionPobeditela, potionMedic, potionSernaya, potionAgent, potionOtrizhka, sphereApollona, sphereTitana, talGarmonii, tripwireSphere, trapka, ledyanka, netheriteIngot, enchantedGoldenApple));
    }
}
ClientItem и Check к нему:


Код:
package me.funtimeutils.util.items.item;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import lombok.Getter;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.PotionUtil;
import net.minecraft.text.Text;

import java.util.*;

@Getter
public class ClientItem {
    private final List<String> containsTooltip = new ArrayList<>();
    private final Map<Enchantment, Integer> containsEnchantments = new HashMap<>();
    private final List<StatusEffectInstance> effects = new ArrayList<>();
    private String tag;
    protected Check check;
    private String name;

    /**
     * Аттрибуты
     */

    private final Multimap<EntityAttribute, EntityAttributeModifier> attributes = HashMultimap.create();

    public ClientItem name(String name) {
        this.name = name;
        return this;
    }

    public ClientItem check(Check check) {
        this.check = check;
        return this;
    }

    public ClientItem tag(String tag) {
        this.tag = tag;
        return this;
    }
   
    private void addTooltip(String component) {
        this.containsTooltip.add(component);
    }

    public ClientItem addTooltips(String... ss) {
        for (String s : ss)
            this.addTooltip(s);

        return this;
    }
   
    // Можете добавить свои зачары чтобы добавить например незеритовые поножи на защиту 4
    public ClientItem addEnchantment(Enchantment enc, int amp) {
        if (containsEnchantments.containsKey(enc))
            return this;

        this.containsEnchantments.put(enc, amp);
        return this;
    }

    public ClientItem addEffect(StatusEffect effect, int amp, int duration) {
        this.effects.add(new StatusEffectInstance(effect, duration, amp));
        return this;
    }

    public ClientItem addAttribute(EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        this.attributes.put(attribute, new EntityAttributeModifier(attribute.getTranslationKey(), value, operation));
        return this;
    }

    private boolean containsAttribute(EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        List<EntityAttributeModifier> matchingModifiers = new ArrayList<>();

        for (EntityAttribute attribute1 : attributes.keySet()) {
            if (attribute1 != attribute)
                continue;

            for (EntityAttributeModifier modifier : attributes.get(attribute))
                if (modifier.getOperation() == operation && modifier.getValue() == value)
                    matchingModifiers.add(modifier);
        }

        return !matchingModifiers.isEmpty();
    }

    public boolean containsAllAttributes(ItemStack stack) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = stack.getAttributeModifiers(EquipmentSlot.OFFHAND);

        if (attributes.size() != this.attributes.size())
            return false;

        for (Map.Entry<EntityAttribute, EntityAttributeModifier> entry : attributes.entries()) {
            EntityAttribute key = entry.getKey();
            EntityAttributeModifier value = entry.getValue();

            if (!containsAttribute(key, value.getValue(), value.getOperation())) {
                return false;
            }
        }

        return true;
    }

    public boolean containsAllEffects(ItemStack stack) {
        List<StatusEffectInstance> itemEffects = PotionUtil.getPotionEffects(stack);

        if (effects.size() != itemEffects.size())
            return false;

        for (StatusEffectInstance effect : effects) {
            boolean matchFound = false;

            for (StatusEffectInstance itemEffect : itemEffects) {
                if (itemEffect.getEffectType().equals(effect.getEffectType()) && itemEffect.getAmplifier() <= effect.getAmplifier()) {
                    matchFound = true;
                    break;
                }
            }

            if (!matchFound) {
                return false;
            }
        }

        return true;
    }

    // Чтобы чекать на наличие зачаров на броне
    public boolean containsAllEnchantments(ItemStack stack) {
        Map<Enchantment, Integer> enchantments = EnchantmentHelper.get(stack);
       
        for (Enchantment ench : this.containsEnchantments.keySet()) {
            int value = this.containsEnchantments.get(ench);

            if (!enchantments.containsKey(ench) || enchantments.get(ench) != value)
                return false;
        }

        return true;
    }

    public boolean containsAllTooltip(ItemStack stack) {
        List<Text> components = getTooltip(stack);

        for (String s : this.containsTooltip) {
            if (!contains(components, s))
                return false;
        }

        return true;
    }

    private List<Text> getTooltip(ItemStack stack) {
        final MinecraftClient mc = MinecraftClient.getInstance();

        return stack.getTooltip(mc.player, mc.options.advancedItemTooltips ? TooltipContext.Default.ADVANCED : TooltipContext.Default.NORMAL);
    }

    private boolean contains(List<Text> list, String found) {
        for (Text t : list)
            if (t.getString().contains(found))
                return true;

        return false;
    }
   
}
Код:
package me.funtimeutils.util.items.item;

import net.minecraft.item.ItemStack;

@FunctionalInterface
public interface Check {
    boolean check(ClientItem item, ItemStack stack);
}
LevelItem и Check к нему


Код:
package me.funtimeutils.util.items.item.level;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import lombok.Getter;
import lombok.Setter;
import me.funtimeutils.util.items.item.ClientItem;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Getter
@Setter
public class LevelItem extends ClientItem {
    private LevelCheck levelCheck;
    private int level;

    @Override
    public String getName() {
        return super.getName() + " " + (level == 3 ? "MAX" : level) + " уровня";
    }

    public LevelItem lcheck(LevelCheck check) {
        this.levelCheck = check;
        return this;
    }

    @Override
    public LevelItem name(String name) {
        super.name(name);
        return this;
    }

    public LevelItem withLevel(int level) {
        this.level = level;
        return this;
    }

    private boolean containsAttribute(Multimap<EntityAttribute, EntityAttributeModifier> attributes, EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        List<EntityAttributeModifier> matchingModifiers = new ArrayList<>();

        for (EntityAttribute attribute1 : attributes.keySet()) {
            if (attribute1 != attribute)
                continue;

            for (EntityAttributeModifier modifier : attributes.get(attribute))
                if (modifier.getOperation() == operation && modifier.getValue() == value)
                    matchingModifiers.add(modifier);
        }

        return !matchingModifiers.isEmpty();
    }

    public boolean containsAllAttributes(List<EntityAttribute> list, List<EntityAttributeModifier> modifiers, ItemStack stack, boolean withSize) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = stack.getAttributeModifiers(EquipmentSlot.OFFHAND);
        Multimap<EntityAttribute, EntityAttributeModifier> att = attributesFromLists(list, modifiers);

        if (att.isEmpty())
            return false;

        if (withSize && att.size() != attributes.size())
            return false;

        for (Map.Entry<EntityAttribute, EntityAttributeModifier> entry : att.entries()) {
            EntityAttribute key = entry.getKey();
            EntityAttributeModifier value = entry.getValue();

            if (!containsAttribute(attributes, key, value.getValue(), value.getOperation()))
                return false;
        }

        return true;
    }

    private Multimap<EntityAttribute, EntityAttributeModifier> attributesFromLists(List<EntityAttribute> list, List<EntityAttributeModifier> modifiers) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = HashMultimap.create();

        for (EntityAttribute attribute : list) {
            EntityAttributeModifier modifier = modifiers.get(list.indexOf(attribute));

            attributes.put(attribute, modifier);
        }

        return attributes;
    }
}

Код:
package me.funtimeutils.util.items.item.level;

import net.minecraft.item.ItemStack;

@FunctionalInterface
public interface LevelCheck {
    int check(LevelItem levelItem, ItemStack stack);
}
ItemStorage

Код:
package me.funtimeutils.util;

import com.google.common.eventbus.Subscribe;
import lombok.Getter;
import me.funtimeutils.event.impl.EventTick;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;

import java.util.ArrayList;
import java.util.List;

@Getter
public class ItemStorage {
    @Getter
    private static ItemStorage Instance;
    private final MinecraftClient mc = MinecraftClient.getInstance();
    private final List<ItemEntity> itemEntities = new ArrayList<>();

    public ItemStorage() {
        Instance = this;
    }

    @Subscribe
    public void onTick(EventTick e) {
        itemEntities.clear();

        assert mc.world != null;
        for (Entity entity : mc.world.getEntities()) {
            if (!(entity instanceof ItemEntity))
                continue;

            ItemEntity item = (ItemEntity) entity;

            itemEntities.add(item);
        }
    }

}

Мб кому-то нужен будет Mixin, чтобы понимать где происходит пост ивента EventRender3D


Код:
package me.funtimeutils.mixin;

import me.funtimeutils.FuntimeUtils;
import me.funtimeutils.event.impl.EventRender3D;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.LightmapTextureManager;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Matrix4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(WorldRenderer.class)
public class MixinWorldRenderer {

    @Unique
    EventRender3D eventRender3D;

    @Inject(at = @At("RETURN"), method = "render")
    private void render(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
        eventRender3D = new EventRender3D(matrices, tickDelta);
        FuntimeUtils.getInstance().getEventBus().post(eventRender3D);
    }

}
Все утилиты


Код:
    public static MatrixStack matrixFrom(double x, double y, double z) {
        MatrixStack matrices = new MatrixStack();

        Camera camera = mc.gameRenderer.getCamera();
        matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(camera.getPitch()));
        matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(camera.getYaw() + 180.0F));

        matrices.translate(x - camera.getPos().x, y - camera.getPos().y, z - camera.getPos().z);

        return matrices;
    }

    public Vec3d getInterpolationOffset(Entity e) {
        float tickDelta = mc.getTickDelta();

        double posX = e.getX() - MathHelper.lerp(tickDelta, e.prevX, e.getX());
        double posY = e.getY() - MathHelper.lerp(tickDelta, e.prevY, e.getY());
        double posZ = e.getZ() - MathHelper.lerp(tickDelta, e.prevZ, e.getZ());

        return new Vec3d(posX, posY, posZ);
    }

    public void drawText(Text text, double x, double y, double z, double scale, boolean shadow) {
        drawText(text, x, y, z, 0, 0, scale, shadow);
    }

    public void drawText(Text text, double x, double y, double z, double offX, double offY, double scale, boolean fill) {
        MatrixStack matrices = matrixFrom(x, y, z);

        Camera camera = mc.gameRenderer.getCamera();
        matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(-camera.getYaw()));
        matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(camera.getPitch()));

        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();

        matrices.translate(offX, offY, 0);
        matrices.scale(-0.025f * (float) scale, -0.025f * (float) scale, 1);

        int halfWidth = mc.textRenderer.getWidth(text.getString()) / 2;

        VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());

        if (fill) {
            int opacity = (int) (MinecraftClient.getInstance().options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24;
            mc.textRenderer.draw(text, -halfWidth, 0f, 553648127, false, matrices.peek().getModel(), immediate, true, opacity, 0xf000f0);
            immediate.draw();
        } else {
            matrices.push();
            matrices.translate(1, 1, 0);
            mc.textRenderer.draw(text.copy(), -halfWidth, 0f, 0x202020, false, matrices.peek().getModel(), immediate, true, 0, 0xf000f0);
            immediate.draw();
            matrices.pop();
        }

        mc.textRenderer.draw(text, -halfWidth, 0f, -1, false, matrices.peek().getModel(), immediate, true, 0, 0xf000f0);
        immediate.draw();

        RenderSystem.disableBlend();
    }
ss:

Посмотреть вложение 283688
Удачи вам адаптировать всё это под mcp!
+ реп
 
Начинающий
Статус
Оффлайн
Регистрация
12 Мар 2024
Сообщения
21
Реакции[?]
0
Поинты[?]
0
Увидел какую-то тему с убогими ItemESP, решил вам слить свои, написано если что под fabric 1.16.5

Сама функция ItemESP


Код:
package me.funtimeutils.module.impl;

import com.google.common.eventbus.Subscribe;
import com.mojang.blaze3d.systems.RenderSystem;
import me.funtimeutils.FuntimeUtils;
import me.funtimeutils.event.impl.EventRender3D;
import me.funtimeutils.module.api.Module;
import me.funtimeutils.module.api.ModuleInfo;
import me.funtimeutils.util.ItemStorage;
import me.funtimeutils.util.items.item.ClientItem;
import me.funtimeutils.util.render.RenderUtils;
import net.minecraft.entity.ItemEntity;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.Vec3d;

@ModuleInfo(name = "ItemESP", description = "Показывает донатные предметы")
public class ItemESP extends Module {

    @Subscribe
    public void onRender3D(EventRender3D e) {
        for (ItemEntity item : ItemStorage.getInstance().getItemEntities()) {
            ClientItem clientItem = FuntimeUtils.getInstance().getItemList().getItem(item.getStack());

            if (clientItem == null)
                continue;

            Vec3d pos = item.getPos().subtract(RenderUtils.getInterpolationOffset(item)).add(0, item.getEyeHeight(item.getPose()) + 0.75, 0);
            Vec3d interpolationOffset = RenderUtils.getInterpolationOffset(mc.player);

            Vec3d playerPos = mc.player.getPos().subtract(interpolationOffset);

            double scale = Math.max(2, playerPos.distanceTo(pos) / 3.5);

            RenderSystem.disableDepthTest();
            RenderSystem.depthMask(false);

            LiteralText text = new LiteralText(Formatting.RED + clientItem.getName() + " x" + item.getStack().getCount());

            RenderUtils.drawText(text, pos.x, pos.y, pos.z, scale, true);

            RenderSystem.depthMask(true);
            RenderSystem.enableDepthTest();
        }
    }

}
ItemList, объявите его где-нибудь в вашем коде:


Код:
package me.funtimeutils.util.items;

import me.funtimeutils.util.ChatUtil;
import me.funtimeutils.util.items.item.ClientItem;
import me.funtimeutils.util.items.item.level.LevelItem;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static net.minecraft.entity.attribute.EntityAttributeModifier.Operation.ADDITION;
import static net.minecraft.entity.attribute.EntityAttributeModifier.Operation.MULTIPLY_BASE;
import static net.minecraft.entity.attribute.EntityAttributes.*;
import static net.minecraft.entity.attribute.EntityAttributes.GENERIC_ATTACK_DAMAGE;
import static net.minecraft.entity.effect.StatusEffects.*;
import static net.minecraft.entity.effect.StatusEffects.SPEED;
import static net.minecraft.item.Items.*;

public class ItemList {
    private final List<ClientItem> items = new ArrayList<>();

    ClientItem tripwireSphere = new ClientItem()
            .name("Отмычка к сферам")
            .addTooltips("Этой отмычкой можно", "Открыть хранилище", "С Сферами")
            .check((item, stack) -> stack.getItem() == TRIPWIRE_HOOK && item.containsAllTooltip(stack));

    ClientItem trapka = new ClientItem()
            .name("Трапка")
            .tag("trap")
            .check((item, stack) -> stack.getTag() != null && stack.hasTag() && stack.getTag().contains(item.getTag()));

    ClientItem ledyanka = new ClientItem()
            .name("Ледяная стрела")
            .addEffect(SLOWNESS, 50, 100)
            .addEffect(WEAKNESS, 0, 120)
            .check((item, stack) -> stack.getItem() == TIPPED_ARROW && item.containsAllEffects(stack));

    ClientItem netheriteIngot = new ClientItem()
            .name("Незеритовый слиток")
            .check((item, stack) -> stack.getItem() == NETHERITE_INGOT);

    ClientItem enchantedGoldenApple = new ClientItem()
            .name("Чарка")
            .check((item, stack) -> stack.getItem() == ENCHANTED_GOLDEN_APPLE);

    ClientItem potionKillera = new ClientItem().name("Зелье Киллера")
            .addEffect(STRENGTH, 3, 3600)
            .addEffect(RESISTANCE, 0, 3600)
            .check(ClientItem::containsAllEffects);

    ClientItem potionPobeditela = new ClientItem()
            .name("Зелье Победителя")
            .addEffect(HEALTH_BOOST, 1, 3600)
            .addEffect(RESISTANCE, 0, 1200)
            .addEffect(INVISIBILITY, 0, 18000)
            .addEffect(REGENERATION, 1, 1200)
            .check(ClientItem::containsAllEffects);

    ClientItem potionMedic = new ClientItem()
            .name("Зелье Медика")
            .addEffect(HEALTH_BOOST, 2, 900)
            .addEffect(REGENERATION, 2, 900)
            .check(ClientItem::containsAllEffects);

    ClientItem potionSernaya = new ClientItem()
            .name("Серная Кислота")
            .addEffect(POISON, 1, 1000)
            .addEffect(SLOWNESS, 3, 1800)
            .addEffect(WEAKNESS, 2, 1800)
            .addEffect(WITHER, 4, 600)
            .check(ClientItem::containsAllEffects);

    ClientItem potionAgent = new ClientItem()
            .name("Зелье Агента")
            .addEffect(INVISIBILITY, 1, 18000)
            .addEffect(FIRE_RESISTANCE, 0, 18000)
            .addEffect(SPEED, 2, 18000)
            .addEffect(HASTE, 0, 3500)
            .addEffect(STRENGTH, 2, 6000)
            .check(ClientItem::containsAllEffects);

    ClientItem potionOtrizhka = new ClientItem()
            .name("Зелье Отрыжки")
            .addEffect(BLINDNESS, 0, 200)
            .addEffect(GLOWING, 0, 3600)
            .addEffect(HUNGER, 10, 1800)
            .addEffect(SLOWNESS, 2, 3600)
            .addEffect(WITHER, 4, 600)
            .check(ClientItem::containsAllEffects);

    LevelItem sphereApollona = new LevelItem()
            .name("Сфера Аполлона")
            .lcheck((item, stack) -> {
                if (stack.getItem() != PLAYER_HEAD)
                    return -1;

                if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(3, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 2;
                else if (item.containsAllAttributes(Arrays.asList(GENERIC_ATTACK_DAMAGE, GENERIC_MOVEMENT_SPEED), Arrays.asList(fromValueOperation(4, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, true))
                    return 3;

                return -1;
            });

    LevelItem sphereTitana = new LevelItem()
            .name("Сфера Титана")
            .lcheck((item, stack) -> {
                if (stack.getItem() != PLAYER_HEAD)
                    return -1;

                List<EntityAttribute> attributes = Arrays.asList(GENERIC_ARMOR, GENERIC_ARMOR_TOUGHNESS);
                List<EntityAttribute> attributes1 = Arrays.asList(GENERIC_ARMOR, GENERIC_ARMOR_TOUGHNESS, GENERIC_MOVEMENT_SPEED);

                if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1, ADDITION), fromValueOperation(1, ADDITION)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(attributes1, Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION), fromValueOperation(-0.1, MULTIPLY_BASE)), stack, false))
                    return 2;
                else if (item.containsAllAttributes(attributes1, Arrays.asList(fromValueOperation(3, ADDITION), fromValueOperation(3, ADDITION), fromValueOperation(-0.15, MULTIPLY_BASE)), stack, false))
                    return 3;

                return -1;
            });

    LevelItem talGarmonii = new LevelItem()
            .name("Талисман Гармонии")
            .lcheck((item, stack) -> {
                if (stack.getItem() != TOTEM_OF_UNDYING)
                    return -1;

                List<EntityAttribute> attributes = Arrays.asList(GENERIC_ARMOR, GENERIC_MAX_HEALTH, GENERIC_ATTACK_DAMAGE);

                if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1,ADDITION), fromValueOperation(1, ADDITION), fromValueOperation(1, ADDITION)), stack, true))
                    return 1;
                else if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(1.5, ADDITION), fromValueOperation(1.5, ADDITION), fromValueOperation(1.5, ADDITION)), stack, true))
                    return 2;
                else if (item.containsAllAttributes(attributes, Arrays.asList(fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION), fromValueOperation(2, ADDITION)), stack, true))
                    return 3;

                return -1;
            });
   
    // Дальше если что можете сами добавлять предметы, которые вам нужны, например божья аура и т.д.

    public ItemList() {
        reload();
    }

    private EntityAttributeModifier fromValueOperation(double value, EntityAttributeModifier.Operation operation) {
        return new EntityAttributeModifier("aa", value, operation);
    }

    public ClientItem getItem(ItemStack stack) {
        assert stack.getTag() != null;

        for (ClientItem item : items) {
            if (item instanceof ClientItem) {
                if (!(item instanceof LevelItem)) {
                    if (item.getCheck() == null) {
                        ChatUtil.addMessage("Null Check: " + item.getName());
                        break;
                    }

                    if (item.getCheck().check(item, stack)) {
                        return item;
                    }
                } else {
                    LevelItem levelItem = (LevelItem) item;

                    if (levelItem.getLevelCheck() == null) {
                        ChatUtil.addMessage("Level Item Null Check " + levelItem.getName());
                        break;
                    }

                    if (levelItem.getLevelCheck().check(levelItem, stack) != -1)
                        return levelItem.withLevel(levelItem.getLevelCheck().check(levelItem, stack));
                }
            }
        }

        return null;
    }

    public void reload() {
        this.items.clear();

        items.addAll(Arrays.asList(potionKillera, potionPobeditela, potionMedic, potionSernaya, potionAgent, potionOtrizhka, sphereApollona, sphereTitana, talGarmonii, tripwireSphere, trapka, ledyanka, netheriteIngot, enchantedGoldenApple));
    }
}
ClientItem и Check к нему:


Код:
package me.funtimeutils.util.items.item;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import lombok.Getter;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.PotionUtil;
import net.minecraft.text.Text;

import java.util.*;

@Getter
public class ClientItem {
    private final List<String> containsTooltip = new ArrayList<>();
    private final Map<Enchantment, Integer> containsEnchantments = new HashMap<>();
    private final List<StatusEffectInstance> effects = new ArrayList<>();
    private String tag;
    protected Check check;
    private String name;

    /**
     * Аттрибуты
     */

    private final Multimap<EntityAttribute, EntityAttributeModifier> attributes = HashMultimap.create();

    public ClientItem name(String name) {
        this.name = name;
        return this;
    }

    public ClientItem check(Check check) {
        this.check = check;
        return this;
    }

    public ClientItem tag(String tag) {
        this.tag = tag;
        return this;
    }
   
    private void addTooltip(String component) {
        this.containsTooltip.add(component);
    }

    public ClientItem addTooltips(String... ss) {
        for (String s : ss)
            this.addTooltip(s);

        return this;
    }
   
    // Можете добавить свои зачары чтобы добавить например незеритовые поножи на защиту 4
    public ClientItem addEnchantment(Enchantment enc, int amp) {
        if (containsEnchantments.containsKey(enc))
            return this;

        this.containsEnchantments.put(enc, amp);
        return this;
    }

    public ClientItem addEffect(StatusEffect effect, int amp, int duration) {
        this.effects.add(new StatusEffectInstance(effect, duration, amp));
        return this;
    }

    public ClientItem addAttribute(EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        this.attributes.put(attribute, new EntityAttributeModifier(attribute.getTranslationKey(), value, operation));
        return this;
    }

    private boolean containsAttribute(EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        List<EntityAttributeModifier> matchingModifiers = new ArrayList<>();

        for (EntityAttribute attribute1 : attributes.keySet()) {
            if (attribute1 != attribute)
                continue;

            for (EntityAttributeModifier modifier : attributes.get(attribute))
                if (modifier.getOperation() == operation && modifier.getValue() == value)
                    matchingModifiers.add(modifier);
        }

        return !matchingModifiers.isEmpty();
    }

    public boolean containsAllAttributes(ItemStack stack) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = stack.getAttributeModifiers(EquipmentSlot.OFFHAND);

        if (attributes.size() != this.attributes.size())
            return false;

        for (Map.Entry<EntityAttribute, EntityAttributeModifier> entry : attributes.entries()) {
            EntityAttribute key = entry.getKey();
            EntityAttributeModifier value = entry.getValue();

            if (!containsAttribute(key, value.getValue(), value.getOperation())) {
                return false;
            }
        }

        return true;
    }

    public boolean containsAllEffects(ItemStack stack) {
        List<StatusEffectInstance> itemEffects = PotionUtil.getPotionEffects(stack);

        if (effects.size() != itemEffects.size())
            return false;

        for (StatusEffectInstance effect : effects) {
            boolean matchFound = false;

            for (StatusEffectInstance itemEffect : itemEffects) {
                if (itemEffect.getEffectType().equals(effect.getEffectType()) && itemEffect.getAmplifier() <= effect.getAmplifier()) {
                    matchFound = true;
                    break;
                }
            }

            if (!matchFound) {
                return false;
            }
        }

        return true;
    }

    // Чтобы чекать на наличие зачаров на броне
    public boolean containsAllEnchantments(ItemStack stack) {
        Map<Enchantment, Integer> enchantments = EnchantmentHelper.get(stack);
       
        for (Enchantment ench : this.containsEnchantments.keySet()) {
            int value = this.containsEnchantments.get(ench);

            if (!enchantments.containsKey(ench) || enchantments.get(ench) != value)
                return false;
        }

        return true;
    }

    public boolean containsAllTooltip(ItemStack stack) {
        List<Text> components = getTooltip(stack);

        for (String s : this.containsTooltip) {
            if (!contains(components, s))
                return false;
        }

        return true;
    }

    private List<Text> getTooltip(ItemStack stack) {
        final MinecraftClient mc = MinecraftClient.getInstance();

        return stack.getTooltip(mc.player, mc.options.advancedItemTooltips ? TooltipContext.Default.ADVANCED : TooltipContext.Default.NORMAL);
    }

    private boolean contains(List<Text> list, String found) {
        for (Text t : list)
            if (t.getString().contains(found))
                return true;

        return false;
    }
   
}
Код:
package me.funtimeutils.util.items.item;

import net.minecraft.item.ItemStack;

@FunctionalInterface
public interface Check {
    boolean check(ClientItem item, ItemStack stack);
}
LevelItem и Check к нему


Код:
package me.funtimeutils.util.items.item.level;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import lombok.Getter;
import lombok.Setter;
import me.funtimeutils.util.items.item.ClientItem;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.item.ItemStack;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Getter
@Setter
public class LevelItem extends ClientItem {
    private LevelCheck levelCheck;
    private int level;

    @Override
    public String getName() {
        return super.getName() + " " + (level == 3 ? "MAX" : level) + " уровня";
    }

    public LevelItem lcheck(LevelCheck check) {
        this.levelCheck = check;
        return this;
    }

    @Override
    public LevelItem name(String name) {
        super.name(name);
        return this;
    }

    public LevelItem withLevel(int level) {
        this.level = level;
        return this;
    }

    private boolean containsAttribute(Multimap<EntityAttribute, EntityAttributeModifier> attributes, EntityAttribute attribute, double value, EntityAttributeModifier.Operation operation) {
        List<EntityAttributeModifier> matchingModifiers = new ArrayList<>();

        for (EntityAttribute attribute1 : attributes.keySet()) {
            if (attribute1 != attribute)
                continue;

            for (EntityAttributeModifier modifier : attributes.get(attribute))
                if (modifier.getOperation() == operation && modifier.getValue() == value)
                    matchingModifiers.add(modifier);
        }

        return !matchingModifiers.isEmpty();
    }

    public boolean containsAllAttributes(List<EntityAttribute> list, List<EntityAttributeModifier> modifiers, ItemStack stack, boolean withSize) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = stack.getAttributeModifiers(EquipmentSlot.OFFHAND);
        Multimap<EntityAttribute, EntityAttributeModifier> att = attributesFromLists(list, modifiers);

        if (att.isEmpty())
            return false;

        if (withSize && att.size() != attributes.size())
            return false;

        for (Map.Entry<EntityAttribute, EntityAttributeModifier> entry : att.entries()) {
            EntityAttribute key = entry.getKey();
            EntityAttributeModifier value = entry.getValue();

            if (!containsAttribute(attributes, key, value.getValue(), value.getOperation()))
                return false;
        }

        return true;
    }

    private Multimap<EntityAttribute, EntityAttributeModifier> attributesFromLists(List<EntityAttribute> list, List<EntityAttributeModifier> modifiers) {
        Multimap<EntityAttribute, EntityAttributeModifier> attributes = HashMultimap.create();

        for (EntityAttribute attribute : list) {
            EntityAttributeModifier modifier = modifiers.get(list.indexOf(attribute));

            attributes.put(attribute, modifier);
        }

        return attributes;
    }
}

Код:
package me.funtimeutils.util.items.item.level;

import net.minecraft.item.ItemStack;

@FunctionalInterface
public interface LevelCheck {
    int check(LevelItem levelItem, ItemStack stack);
}
ItemStorage

Код:
package me.funtimeutils.util;

import com.google.common.eventbus.Subscribe;
import lombok.Getter;
import me.funtimeutils.event.impl.EventTick;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;

import java.util.ArrayList;
import java.util.List;

@Getter
public class ItemStorage {
    @Getter
    private static ItemStorage Instance;
    private final MinecraftClient mc = MinecraftClient.getInstance();
    private final List<ItemEntity> itemEntities = new ArrayList<>();

    public ItemStorage() {
        Instance = this;
    }

    @Subscribe
    public void onTick(EventTick e) {
        itemEntities.clear();

        assert mc.world != null;
        for (Entity entity : mc.world.getEntities()) {
            if (!(entity instanceof ItemEntity))
                continue;

            ItemEntity item = (ItemEntity) entity;

            itemEntities.add(item);
        }
    }

}

Мб кому-то нужен будет Mixin, чтобы понимать где происходит пост ивента EventRender3D


Код:
package me.funtimeutils.mixin;

import me.funtimeutils.FuntimeUtils;
import me.funtimeutils.event.impl.EventRender3D;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.LightmapTextureManager;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Matrix4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(WorldRenderer.class)
public class MixinWorldRenderer {

    @Unique
    EventRender3D eventRender3D;

    @Inject(at = @At("RETURN"), method = "render")
    private void render(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
        eventRender3D = new EventRender3D(matrices, tickDelta);
        FuntimeUtils.getInstance().getEventBus().post(eventRender3D);
    }

}
Все утилиты


Код:
    public static MatrixStack matrixFrom(double x, double y, double z) {
        MatrixStack matrices = new MatrixStack();

        Camera camera = mc.gameRenderer.getCamera();
        matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(camera.getPitch()));
        matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(camera.getYaw() + 180.0F));

        matrices.translate(x - camera.getPos().x, y - camera.getPos().y, z - camera.getPos().z);

        return matrices;
    }

    public Vec3d getInterpolationOffset(Entity e) {
        float tickDelta = mc.getTickDelta();

        double posX = e.getX() - MathHelper.lerp(tickDelta, e.prevX, e.getX());
        double posY = e.getY() - MathHelper.lerp(tickDelta, e.prevY, e.getY());
        double posZ = e.getZ() - MathHelper.lerp(tickDelta, e.prevZ, e.getZ());

        return new Vec3d(posX, posY, posZ);
    }

    public void drawText(Text text, double x, double y, double z, double scale, boolean shadow) {
        drawText(text, x, y, z, 0, 0, scale, shadow);
    }

    public void drawText(Text text, double x, double y, double z, double offX, double offY, double scale, boolean fill) {
        MatrixStack matrices = matrixFrom(x, y, z);

        Camera camera = mc.gameRenderer.getCamera();
        matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion(-camera.getYaw()));
        matrices.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(camera.getPitch()));

        RenderSystem.enableBlend();
        RenderSystem.defaultBlendFunc();

        matrices.translate(offX, offY, 0);
        matrices.scale(-0.025f * (float) scale, -0.025f * (float) scale, 1);

        int halfWidth = mc.textRenderer.getWidth(text.getString()) / 2;

        VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());

        if (fill) {
            int opacity = (int) (MinecraftClient.getInstance().options.getTextBackgroundOpacity(0.25F) * 255.0F) << 24;
            mc.textRenderer.draw(text, -halfWidth, 0f, 553648127, false, matrices.peek().getModel(), immediate, true, opacity, 0xf000f0);
            immediate.draw();
        } else {
            matrices.push();
            matrices.translate(1, 1, 0);
            mc.textRenderer.draw(text.copy(), -halfWidth, 0f, 0x202020, false, matrices.peek().getModel(), immediate, true, 0, 0xf000f0);
            immediate.draw();
            matrices.pop();
        }

        mc.textRenderer.draw(text, -halfWidth, 0f, -1, false, matrices.peek().getModel(), immediate, true, 0, 0xf000f0);
        immediate.draw();

        RenderSystem.disableBlend();
    }
ss:

Посмотреть вложение 283688
Удачи вам адаптировать всё это под mcp!
как это сделать под Forge
 
Сверху Снизу