Skip to content

Commit

Permalink
Refactor CompactorDeletorPreview and add option
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinthegreat1 committed Sep 15, 2023
1 parent 63f8b9f commit 3881303
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ public ItemData(String itemName) {
public static class General {
public boolean acceptReparty = true;
public boolean backpackPreviewWithoutShift = false;
public boolean compactorDeletorPreview = true;
public boolean hideEmptyTooltips = true;

@ConfigEntry.Category("tabHud")
Expand Down
24 changes: 13 additions & 11 deletions src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@

import me.xmrvizzy.skyblocker.SkyblockerMod;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import me.xmrvizzy.skyblocker.mixin.accessor.DrawContextInvoker;
import me.xmrvizzy.skyblocker.skyblock.item.BackpackPreview;
import me.xmrvizzy.skyblocker.skyblock.experiment.ChronomatronSolver;
import me.xmrvizzy.skyblocker.skyblock.experiment.ExperimentSolver;
import me.xmrvizzy.skyblocker.skyblock.experiment.SuperpairsSolver;
import me.xmrvizzy.skyblocker.skyblock.experiment.UltrasequencerSolver;
import me.xmrvizzy.skyblocker.skyblock.item.BackpackPreview;
import me.xmrvizzy.skyblocker.skyblock.item.CompactorDeletorPreview;
import me.xmrvizzy.skyblocker.skyblock.item.WikiLookup;
import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry;
Expand All @@ -34,6 +33,7 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.Map;
import java.util.regex.Matcher;

@Mixin(HandledScreen.class)
public abstract class HandledScreenMixin extends Screen {
Expand All @@ -52,27 +52,30 @@ protected HandledScreenMixin(Text title) {
}
}

@SuppressWarnings("DataFlowIssue") // makes intellij be quiet about this.focusedSlot maybe being null. It's already null checked in mixined method.
@SuppressWarnings("DataFlowIssue")
// makes intellij be quiet about this.focusedSlot maybe being null. It's already null checked in mixined method.
@Inject(method = "drawMouseoverTooltip", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawTooltip(Lnet/minecraft/client/font/TextRenderer;Ljava/util/List;Ljava/util/Optional;II)V"), cancellable = true)
public void skyblocker$drawMouseOverTooltip(DrawContext context, int x, int y, CallbackInfo ci) {
ItemStack stack = this.focusedSlot.getStack();
String internalName = ItemRegistry.getInternalName(stack);
if (!Utils.isOnSkyblock()) return;

// Hide Empty Tooltips
if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.hideEmptyTooltips && this.focusedSlot != null && focusedSlot.getStack().getName().getString().equals(" ")) {
if (SkyblockerConfig.get().general.hideEmptyTooltips && focusedSlot.getStack().getName().getString().equals(" ")) {
ci.cancel();
}

// Backpack Preview
boolean shiftDown = SkyblockerConfig.get().general.backpackPreviewWithoutShift ^ Screen.hasShiftDown();
if (this.client == null || this.client.player == null) return;
if (shiftDown && this.getTitle().getString().equals("Storage") && this.focusedSlot.inventory != this.client.player.getInventory() && BackpackPreview.renderPreview(context, this.focusedSlot.getIndex(), x, y)) {
if (shiftDown && getTitle().getString().equals("Storage") && focusedSlot.inventory != client.player.getInventory() && BackpackPreview.renderPreview(context, focusedSlot.getIndex(), x, y)) {
ci.cancel();
}

// Compactor Preview
if ((internalName.contains("PERSONAL_COMPACTOR_") || internalName.contains("PERSONAL_DELETOR_")) && CompactorDeletorPreview.displayCompactorDeletorPreview((DrawContextInvoker) context, x, y, stack)) {
ci.cancel();
if (SkyblockerConfig.get().general.compactorDeletorPreview) {
ItemStack stack = focusedSlot.getStack();
Matcher matcher = CompactorDeletorPreview.NAME.matcher(ItemRegistry.getInternalName(stack));
if (matcher.matches() && CompactorDeletorPreview.drawPreview(context, stack, matcher.group("type"), matcher.group("size"), x, y)) {
ci.cancel();
}
}
}

Expand All @@ -87,7 +90,6 @@ protected HandledScreenMixin(Text title) {
}



@Unique
private ItemStack skyblocker$experimentSolvers$getStack(Slot slot, ItemStack stack) {
ContainerSolver currentSolver = SkyblockerMod.getInstance().containerSolverManager.getCurrentSolver();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
@Mixin(DrawContext.class)
public interface DrawContextInvoker {

@SuppressWarnings("unused")
@Invoker("drawTooltip")
@Invoker
void invokeDrawTooltip(TextRenderer textRenderer, List<TooltipComponent> components, int x, int y, TooltipPositioner positioner);
}
Original file line number Diff line number Diff line change
@@ -1,122 +1,92 @@
package me.xmrvizzy.skyblocker.skyblock.item;

import it.unimi.dsi.fastutil.ints.IntIntPair;
import it.unimi.dsi.fastutil.ints.IntObjectPair;
import me.xmrvizzy.skyblocker.mixin.accessor.DrawContextInvoker;
import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.tooltip.HoveredTooltipPositioner;
import net.minecraft.client.gui.tooltip.TooltipComponent;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.MutableText;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class CompactorDeletorPreview {

private static final MinecraftClient mcClient = MinecraftClient.getInstance();
private static final Map<String, int[]> personalCompactorTypeToSlot = new HashMap<>();
// Lines, and slots per lines
static {
personalCompactorTypeToSlot.put("4000", new int[]{1,1});
personalCompactorTypeToSlot.put("5000", new int[]{1,3});
personalCompactorTypeToSlot.put("6000", new int[]{1,7});
personalCompactorTypeToSlot.put("7000", new int[]{2,6});
personalCompactorTypeToSlot.put("default", new int[]{1,6});
}

public static boolean displayCompactorDeletorPreview(DrawContextInvoker context, int x, int y, ItemStack stack) {
String internalName = ItemRegistry.getInternalName(stack);

String prefix;
String itemSlotPrefix;
if (internalName.contains("PERSONAL_COMPACTOR_")) {
prefix = "PERSONAL_COMPACTOR_";
itemSlotPrefix = "personal_compact_";
} else {
prefix = "PERSONAL_DELETOR_";
itemSlotPrefix = "personal_deletor_";
}

// Find the line to insert component
int targetIndex = -1;
int lineCount = 0;

List<Text> tooltips = Screen.getTooltipFromItem(mcClient, stack);
for (int i = 0; i < tooltips.size(); i++) {
if (tooltips.get(i).getString().isEmpty()) {
lineCount += 1;
}
if (lineCount == 2) {
targetIndex = i;
break;
}
}
/**
* The width and height in slots of the compactor/deletor
*/
private static final Map<String, IntIntPair> DIMENSIONS = Map.of(
"4000", IntIntPair.of(1, 1),
"5000", IntIntPair.of(1, 3),
"6000", IntIntPair.of(1, 7),
"7000", IntIntPair.of(2, 6)
);
private static final IntIntPair DEFAULT_DIMENSION = IntIntPair.of(1, 6);
public static final Pattern NAME = Pattern.compile("PERSONAL_(?<type>COMPACTOR|DELETOR)_(?<size>\\d+)");
private static final MinecraftClient client = MinecraftClient.getInstance();

public static boolean drawPreview(DrawContext context, ItemStack stack, String type, String size, int x, int y) {
List<Text> tooltips = Screen.getTooltipFromItem(client, stack);
int targetIndex = getTargetIndex(tooltips);
if (targetIndex == -1) return false;
List<TooltipComponent> components = new java.util.ArrayList<>(tooltips.stream().map(Text::asOrderedText).map(TooltipComponent::of).toList());

// STUFF
String internalID = ItemRegistry.getInternalName(stack);
String compactorType = internalID.replaceFirst(prefix, "");
int[] dimensions = personalCompactorTypeToSlot.containsKey(compactorType) ? personalCompactorTypeToSlot.get(compactorType) : personalCompactorTypeToSlot.get("default");

// Get items in compactor or deletor
NbtCompound nbt = stack.getNbt();
if (nbt == null || !nbt.contains("ExtraAttributes", 10)) {
return false;
}
NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes");
Set<String> attributesKeys = extraAttributes.getKeys();
List<String> compactorItems = attributesKeys.stream().filter(s -> s.contains(itemSlotPrefix)).toList();
Map<Integer, ItemStack> slotAndItem = new HashMap<>();
// Get the slots and their items from the nbt, which is in the format personal_compact_<slot_number> or personal_deletor_<slot_number>
List<IntObjectPair<ItemStack>> slots = extraAttributes.getKeys().stream().filter(slot -> slot.contains(type.toLowerCase().substring(0, 7))).map(slot -> IntObjectPair.of(Integer.parseInt(slot.substring(17)), ItemRegistry.getItemStack(extraAttributes.getString(slot)))).toList();

List<TooltipComponent> components = tooltips.stream().map(Text::asOrderedText).map(TooltipComponent::of).collect(Collectors.toList());
IntIntPair dimensions = DIMENSIONS.getOrDefault(size, DEFAULT_DIMENSION);

if (compactorItems.isEmpty()) {
int slotsCount = (dimensions[0] * dimensions[1]);
components.add(targetIndex, TooltipComponent.of(Text.literal(
slotsCount + (slotsCount == 1 ? " slot": " slots"))
.fillStyle(Style.EMPTY.withColor(Formatting.DARK_GRAY)).asOrderedText()));
// If there are no items in compactor or deletor
if (slots.isEmpty()) {
int slotsCount = dimensions.leftInt() * dimensions.rightInt();
components.add(targetIndex, TooltipComponent.of(Text.literal(slotsCount + (slotsCount == 1 ? " slot" : " slots")).formatted(Formatting.GRAY).asOrderedText()));

context.invokeDrawTooltip(mcClient.textRenderer, components, x, y, HoveredTooltipPositioner.INSTANCE);
((DrawContextInvoker) context).invokeDrawTooltip(client.textRenderer, components, x, y, HoveredTooltipPositioner.INSTANCE);
return true;
}

compactorItems.forEach(s -> slotAndItem.put(getNumberAtEnd(s, itemSlotPrefix), ItemRegistry.getItemStack(extraAttributes.getString(s))));
// Add the preview tooltip component
components.add(targetIndex, new CompactorPreviewTooltipComponent(slots, dimensions));


components.add(targetIndex, new CompactorPreviewTooltipComponent(slotAndItem, dimensions));
components.add(targetIndex, TooltipComponent.of(Text.literal(" ").append(
Text.literal("Contents:").fillStyle(Style.EMPTY
.withItalic(true)))
.asOrderedText()));
if (attributesKeys.stream().anyMatch(s -> s.contains("PERSONAL_DELETOR_ACTIVE"))) {
MutableText isActiveText = Text.literal("Active: ");
if (extraAttributes.getBoolean("PERSONAL_DELETOR_ACTIVE")) {
components.add(targetIndex, TooltipComponent.of(isActiveText.append(
Text.literal("YES").fillStyle(Style.EMPTY.withBold(true).withColor(Formatting.GREEN))
).asOrderedText()
));
} else {
components.add(targetIndex, TooltipComponent.of(isActiveText.append(
Text.literal("NO").fillStyle(Style.EMPTY.withBold(true).withColor(Formatting.RED))
).asOrderedText()
));
}
// Render accompanying text
components.add(targetIndex, TooltipComponent.of(Text.literal("Contents:").asOrderedText()));
if (extraAttributes.contains("PERSONAL_DELETOR_ACTIVE")) {
components.add(targetIndex, TooltipComponent.of(Text.literal("Active: ")
.append(extraAttributes.getBoolean("PERSONAL_DELETOR_ACTIVE") ? Text.literal("YES").formatted(Formatting.BOLD).formatted(Formatting.GREEN) : Text.literal("NO").formatted(Formatting.BOLD).formatted(Formatting.RED)).asOrderedText()));
}
context.invokeDrawTooltip(mcClient.textRenderer, components, x, y, HoveredTooltipPositioner.INSTANCE);
((DrawContextInvoker) context).invokeDrawTooltip(client.textRenderer, components, x, y, HoveredTooltipPositioner.INSTANCE);
return true;
}

private static Integer getNumberAtEnd(String str, String attributesKey) {
try {
String numberPartOfTheString = str.replace(attributesKey, "");
return Integer.parseInt(numberPartOfTheString);
} catch (NumberFormatException e) {
return 0;
/**
* Finds the target index to insert the preview component, which is the second empty line
*/
private static int getTargetIndex(List<Text> tooltips) {
int targetIndex = -1;
int lineCount = 0;
for (int i = 0; i < tooltips.size(); i++) {
if (tooltips.get(i).getString().isEmpty()) {
lineCount += 1;
}
if (lineCount == 2) {
targetIndex = i;
break;
}
}
return targetIndex;
}
}
Original file line number Diff line number Diff line change
@@ -1,60 +1,54 @@
package me.xmrvizzy.skyblocker.skyblock.item;

import it.unimi.dsi.fastutil.ints.IntIntPair;
import it.unimi.dsi.fastutil.ints.IntObjectPair;
import me.xmrvizzy.skyblocker.SkyblockerMod;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.tooltip.TooltipComponent;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;

import java.util.Map;

public class CompactorPreviewTooltipComponent implements TooltipComponent {

private static final Identifier INVENTORY_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/inventory_background.png");
private final Iterable<IntObjectPair<ItemStack>> items;
private final IntIntPair dimensions;

Map<Integer, ItemStack> items;
int[] dimensions;

public CompactorPreviewTooltipComponent(Map<Integer, ItemStack> items, int[] dimensions) {
public CompactorPreviewTooltipComponent(Iterable<IntObjectPair<ItemStack>> items, IntIntPair dimensions) {
this.items = items;
this.dimensions = dimensions;
}

@Override
public int getHeight() {
return dimensions[0] * 18 + 14;
return dimensions.leftInt() * 18 + 14;
}

@Override
public int getWidth(TextRenderer textRenderer) {
return dimensions[1] * 18 + 14;
return dimensions.rightInt() * 18 + 14;
}

@Override
public void drawItems(TextRenderer textRenderer, int x, int y, DrawContext context) {
context.drawTexture(INVENTORY_TEXTURE, x, y, 0, 0, 7 + dimensions[1] * 18, 7);
context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions[1] * 18, y, 169, 0, 7, 7);
context.drawTexture(INVENTORY_TEXTURE, x, y, 0, 0, 7 + dimensions.rightInt() * 18, 7);
context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions.rightInt() * 18, y, 169, 0, 7, 7);

for (int i = 0; i < dimensions[0]; i++) {
for (int i = 0; i < dimensions.leftInt(); i++) {
context.drawTexture(INVENTORY_TEXTURE, x, y + 7 + i * 18, 0, 7, 7, 18);
for (int j = 0; j < dimensions[1]; j++) {
for (int j = 0; j < dimensions.rightInt(); j++) {
context.drawTexture(INVENTORY_TEXTURE, x + 7 + j * 18, y + 7 + i * 18, 7, 7, 18, 18);
}
context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions[1] * 18, y + 7 + i * 18, 169, 7, 7, 18);
context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions.rightInt() * 18, y + 7 + i * 18, 169, 7, 7, 18);
}
context.drawTexture(INVENTORY_TEXTURE, x, y + 7 + dimensions[0] * 18, 0, 25, 7 + dimensions[1] * 18, 7);
context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions[1] * 18, y + 7 + dimensions[0] * 18, 169, 25, 7, 7);

MatrixStack matrices = context.getMatrices();
for (Integer i : items.keySet()) {
int itemX = x + i % dimensions[1] * 18 + 8;
int itemY = y + i / dimensions[1] * 18 + 8;
matrices.push();
matrices.translate(0, 0, 200);
context.drawItem(items.get(i), itemX, itemY);
context.drawItemInSlot(textRenderer, items.get(i), itemX, itemY);
matrices.pop();
context.drawTexture(INVENTORY_TEXTURE, x, y + 7 + dimensions.leftInt() * 18, 0, 25, 7 + dimensions.rightInt() * 18, 7);
context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions.rightInt() * 18, y + 7 + dimensions.leftInt() * 18, 169, 25, 7, 7);

for (IntObjectPair<ItemStack> entry : items) {
int itemX = x + entry.leftInt() % dimensions.rightInt() * 18 + 8;
int itemY = y + entry.leftInt() / dimensions.rightInt() * 18 + 8;
context.drawItem(entry.right(), itemX, itemY);
context.drawItemInSlot(textRenderer, entry.right(), itemX, itemY);
}
}
}
1 change: 1 addition & 0 deletions src/main/resources/assets/skyblocker/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"text.autoconfig.skyblocker.option.general.quiverWarning.enableQuiverWarningInDungeons": "Enable Quiver Warning In Dungeons",
"text.autoconfig.skyblocker.option.general.quiverWarning.enableQuiverWarningAfterDungeon": "Enable Quiver Warning After a Dungeon",
"text.autoconfig.skyblocker.option.general.backpackPreviewWithoutShift": "View backpack preview without holding Shift",
"text.autoconfig.skyblocker.option.general.compactorDeletorPreview": "Enable Compactor/Deletor Preview",
"text.autoconfig.skyblocker.option.general.tabHud": "Fancy tab HUD",
"text.autoconfig.skyblocker.option.general.tabHud.tabHudEnabled": "Enable fancy tab HUD",
"text.autoconfig.skyblocker.option.general.tabHud.tabHudScale": "Scale factor of fancy tab HUD",
Expand Down

0 comments on commit 3881303

Please sign in to comment.