diff --git a/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderTooltip.java b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderTooltip.java new file mode 100644 index 0000000..9313562 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderTooltip.java @@ -0,0 +1,46 @@ +package me.rigamortis.seppuku.api.event.gui; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.item.ItemStack; + +/** + * created by noil on 11/4/19 at 1:49 PM + */ +public class EventRenderTooltip extends EventCancellable { + + private ItemStack itemStack; + + private int x; + + private int y; + + public EventRenderTooltip(ItemStack itemStack, int x, int y) { + this.itemStack = itemStack; + this.x = x; + this.y = y; + } + + public ItemStack getItemStack() { + return itemStack; + } + + public void setItemStack(ItemStack itemStack) { + this.itemStack = itemStack; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/management/ModuleManager.java b/src/main/java/me/rigamortis/seppuku/impl/management/ModuleManager.java index f8d8e9c..229f82f 100644 --- a/src/main/java/me/rigamortis/seppuku/impl/management/ModuleManager.java +++ b/src/main/java/me/rigamortis/seppuku/impl/management/ModuleManager.java @@ -139,6 +139,7 @@ public final class ModuleManager { add(new SmallShieldModule()); add(new PullDownModule()); add(new PortalFinderModule()); + add(new ShulkerPreviewModule()); this.loadExternalModules(); } diff --git a/src/main/java/me/rigamortis/seppuku/impl/management/PatchManager.java b/src/main/java/me/rigamortis/seppuku/impl/management/PatchManager.java index c2d8121..266699f 100644 --- a/src/main/java/me/rigamortis/seppuku/impl/management/PatchManager.java +++ b/src/main/java/me/rigamortis/seppuku/impl/management/PatchManager.java @@ -56,6 +56,7 @@ public final class PatchManager { this.patchList.add(new GuiBossOverlayPatch()); this.patchList.add(new NetHandlerPlayClientPatch()); this.patchList.add(new ChunkPatch()); + this.patchList.add(new GuiScreenPatch()); //load custom external patches //TODO this needs more testing diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/render/ShulkerPreviewModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/render/ShulkerPreviewModule.java new file mode 100644 index 0000000..8f60721 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/render/ShulkerPreviewModule.java @@ -0,0 +1,83 @@ +package me.rigamortis.seppuku.impl.module.render; + +import me.rigamortis.seppuku.api.event.gui.EventRenderTooltip; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.util.RenderUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.inventory.ItemStackHelper; +import net.minecraft.item.ItemShulkerBox; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.NonNullList; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * created by noil on 11/4/19 at 1:59 PM + */ +public final class ShulkerPreviewModule extends Module { + + public ShulkerPreviewModule() { + super("ShulkerPreview", new String[]{"SPreview", "ShulkerView"}, "Hover over a shulker box to the items inside.", "NONE", -1, ModuleType.RENDER); + } + + @Listener + public void onRenderTooltip(EventRenderTooltip event) { + if (event.getItemStack() == null) + return; + + final Minecraft mc = Minecraft.getMinecraft(); + + if (event.getItemStack().getItem() instanceof ItemShulkerBox) { + ItemStack shulker = event.getItemStack(); + NBTTagCompound tagCompound = shulker.getTagCompound(); + if (tagCompound != null && tagCompound.hasKey("BlockEntityTag", 10)) { + NBTTagCompound blockEntityTag = tagCompound.getCompoundTag("BlockEntityTag"); + if (blockEntityTag.hasKey("Items", 9)) { + event.setCanceled(true); // cancel rendering the old tooltip + + NonNullList nonnulllist = NonNullList.withSize(27, ItemStack.EMPTY); + ItemStackHelper.loadAllItems(blockEntityTag, nonnulllist); // load the itemstacks from the tag to the list + + // store mouse/event coords + int x = event.getX(); + int y = event.getY(); + + // translate to mouse x, y + GlStateManager.translate(x + 10, y - 5, 0); + + GlStateManager.disableLighting(); + GlStateManager.disableDepth(); + // background + RenderUtil.drawRect(-2, -mc.fontRenderer.FONT_HEIGHT - 3, 9 * 16 + 2, 3 * 16 + 2, 0xEE202020); + RenderUtil.drawRect(0, 0, 9 * 16, 3 * 16, 0x99101010); + + // text + mc.fontRenderer.drawStringWithShadow(shulker.getDisplayName(), 0, -mc.fontRenderer.FONT_HEIGHT - 1, 0xFFFFFFFF); + + GlStateManager.enableDepth(); + mc.getRenderItem().zLevel = 150.0F; + RenderHelper.enableGUIStandardItemLighting(); + + // loop through items in shulker inventory + for (int i = 0; i < nonnulllist.size(); i++) { + ItemStack itemStack = nonnulllist.get(i); + int offsetX = (i % 9) * 16; + int offsetY = (i / 9) * 16; + mc.getRenderItem().renderItemAndEffectIntoGUI(itemStack, offsetX, offsetY); + mc.getRenderItem().renderItemOverlayIntoGUI(mc.fontRenderer, itemStack, offsetX, offsetY, null); + } + + RenderHelper.disableStandardItemLighting(); + mc.getRenderItem().zLevel = 0.0F; + GlStateManager.enableLighting(); + + // reverse the translate + GlStateManager.translate(-(x + 10), -(y - 5), 0); + } + } + + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/NoWeatherModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/NoWeatherModule.java index 36783a8..653face 100644 --- a/src/main/java/me/rigamortis/seppuku/impl/module/world/NoWeatherModule.java +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/NoWeatherModule.java @@ -2,6 +2,7 @@ package me.rigamortis.seppuku.impl.module.world; import me.rigamortis.seppuku.api.event.world.EventRainStrength; import me.rigamortis.seppuku.api.module.Module; +import net.minecraft.client.Minecraft; import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; /** @@ -16,6 +17,9 @@ public final class NoWeatherModule extends Module { @Listener public void onRainStrength(EventRainStrength event) { + if (Minecraft.getMinecraft().world == null) + return; + event.setCanceled(true); } diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/GuiScreenPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/GuiScreenPatch.java new file mode 100644 index 0000000..2e1ead5 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/GuiScreenPatch.java @@ -0,0 +1,50 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.gui.EventRenderTooltip; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; +import team.stiff.pomelo.EventManager; + +import static org.objectweb.asm.Opcodes.*; + +/** + * created by noil on 11/4/19 at 2:03 PM + */ +public final class GuiScreenPatch extends ClassPatch { + + public GuiScreenPatch() { + super("net.minecraft.client.gui.GuiScreen", "bli"); + } + + @MethodPatch( + mcpName = "renderToolTip", + notchName = "a", + mcpDesc = "(Lnet/minecraft/item/ItemStack;II)V", + notchDesc = "(Lain;II)V") + public void renderToolTip(MethodNode methodNode, PatchManager.Environment env) { + final InsnList list = new InsnList(); + list.add(new TypeInsnNode(NEW, Type.getInternalName(EventRenderTooltip.class))); + list.add(new InsnNode(DUP)); + list.add(new VarInsnNode(ALOAD, 1)); + list.add(new VarInsnNode(ILOAD, 2)); + list.add(new VarInsnNode(ILOAD, 3)); + list.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventRenderTooltip.class), "", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/item/ItemStack;II)V" : "(Lain;II)V", false)); + list.add(new VarInsnNode(ASTORE, 7)); + list.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + list.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + list.add(new VarInsnNode(ALOAD, 7)); + list.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + list.add(new InsnNode(POP)); + list.add(new VarInsnNode(ALOAD, 7)); + list.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRenderTooltip.class), "isCanceled", "()Z", false)); + final LabelNode jmp = new LabelNode(); + list.add(new JumpInsnNode(IFEQ, jmp)); + list.add(new InsnNode(RETURN)); + list.add(jmp); + methodNode.instructions.insert(list); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/WorldPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/WorldPatch.java index bdfb73f..46d0858 100644 --- a/src/main/java/me/rigamortis/seppuku/impl/patch/WorldPatch.java +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/WorldPatch.java @@ -70,7 +70,7 @@ public final class WorldPatch extends ClassPatch { list.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "getRainStrengthHook", "()Z", false)); final LabelNode jmp = new LabelNode(); list.add(new JumpInsnNode(IFEQ, jmp)); - list.add(new InsnNode(ICONST_0)); + list.add(new InsnNode(FCONST_0)); list.add(new InsnNode(FRETURN)); list.add(jmp); methodNode.instructions.insert(list);