Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize Drill Fuel and Picko Durability with Caching #366

Merged
merged 1 commit into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 5 additions & 8 deletions src/main/java/de/hysky/skyblocker/mixin/ItemMixin.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
package de.hysky.skyblocker.mixin;

import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;

import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.injection.Redirect;

@Mixin(Item.class)
public abstract class ItemMixin {
@WrapOperation(
@Redirect(
method = {"getItemBarColor", "getItemBarStep"},
at = @At(value = "FIELD", target = "Lnet/minecraft/item/Item;maxDamage:I", opcode = Opcodes.GETFIELD)
)
private int skyblocker$handlePickoDrillBar(Item item, Operation<Integer> original, ItemStack stack) {
private int skyblocker$handlePickoDrillBar(Item item, ItemStack stack) {
return stack.getMaxDamage();
}
}
70 changes: 56 additions & 14 deletions src/main/java/de/hysky/skyblocker/mixin/ItemStackMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,90 @@
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.ItemUtils.Durability;
import de.hysky.skyblocker.utils.Utils;
import dev.cbyrne.betterinject.annotations.Inject;
import it.unimi.dsi.fastutil.ints.IntIntPair;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;

@Mixin(ItemStack.class)
public abstract class ItemStackMixin {

@Shadow
public abstract int getDamage();

@Shadow
public abstract void setDamage(int damage);

@Unique
private int maxDamage;

@ModifyReturnValue(method = "getName", at = @At("RETURN"))
private Text skyblocker$customItemNames(Text original) {
if (Utils.isOnSkyblock()) {
if (Utils.isOnSkyblock()) {
return SkyblockerConfigManager.get().general.customItemNames.getOrDefault(ItemUtils.getItemUuid((ItemStack) (Object) this), original);
}

return original;
}

/**
* Updates the durability of this item stack every tick when in the inventory.
*/
@Inject(method = "inventoryTick", at = @At("TAIL"))
private void skyblocker$updateDamage() {
if (!skyblocker$shouldProcess()) {
return;
}
skyblocker$getAndCacheDurability();
}

@ModifyReturnValue(method = "getDamage", at = @At("RETURN"))
private int skyblocker$handleDamage(int original) {
Durability dur = ItemUtils.getDurability((ItemStack) (Object) this);
if (dur != null) {
return dur.max() - dur.current();
// If the durability is already calculated, the original value should be the damage
if (!skyblocker$shouldProcess() || maxDamage != 0) {
return original;
}
return original;
return skyblocker$getAndCacheDurability() ? getDamage() : original;
}

@ModifyReturnValue(method = "getMaxDamage", at = @At("RETURN"))
private int skyblocker$handleMaxDamage(int original) {
Durability dur = ItemUtils.getDurability((ItemStack) (Object) this);
if (dur != null) {
return dur.max();
if (!skyblocker$shouldProcess()) {
return original;
}
return original;
// If the max damage is already calculated, return it
if (maxDamage != 0) {
return maxDamage;
}
return skyblocker$getAndCacheDurability() ? maxDamage : original;
}

@ModifyReturnValue(method = "isDamageable", at = @At("RETURN"))
private boolean skyblocker$handleDamageable(boolean original) {
Durability dur = ItemUtils.getDurability((ItemStack) (Object) this);
if (dur != null) {
return true;
return skyblocker$shouldProcess() || original;
}

@Unique
private boolean skyblocker$shouldProcess() {
return Utils.isOnSkyblock() && SkyblockerConfigManager.get().locations.dwarvenMines.enableDrillFuel && ItemUtils.hasCustomDurability((ItemStack) (Object) this);
}

@Unique
private boolean skyblocker$getAndCacheDurability() {
// Calculate the durability
IntIntPair durability = ItemUtils.getDurability((ItemStack) (Object) this);
// Return if calculating the durability failed
if (durability == null) {
return false;
}
return original;
// Saves the calculated durability
maxDamage = durability.rightInt();
setDamage(durability.rightInt() - durability.leftInt());
return true;
}
}
26 changes: 10 additions & 16 deletions src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package de.hysky.skyblocker.utils;

import com.mojang.brigadier.exceptions.CommandSyntaxException;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import it.unimi.dsi.fastutil.ints.IntIntPair;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.item.ItemStack;
Expand Down Expand Up @@ -105,29 +105,26 @@ public static String getItemUuid(@NotNull ItemStack stack) {
return extraAttributes != null ? extraAttributes.getString(UUID) : "";
}

@Nullable
public static Durability getDurability(@NotNull ItemStack stack) {
if (!Utils.isOnSkyblock() || !SkyblockerConfigManager.get().locations.dwarvenMines.enableDrillFuel || stack.isEmpty()) {
return null;
}

if (getExtraAttributesOptional(stack).filter(extraAttributes -> extraAttributes.contains("drill_fuel") || extraAttributes.getString(ItemUtils.ID).equals("PICKONIMBUS")).isEmpty()) {
return null;
}
public static boolean hasCustomDurability(@NotNull ItemStack stack) {
NbtCompound extraAttributes = getExtraAttributes(stack);
return extraAttributes != null && (extraAttributes.contains("drill_fuel") || extraAttributes.getString(ID).equals("PICKONIMBUS"));
}

@Nullable
public static IntIntPair getDurability(@NotNull ItemStack stack) {
int current = 0;
int max = 0;
String clearFormatting;

for (String line : ItemUtils.getTooltipStrings(stack)) {
for (String line : getTooltipStrings(stack)) {
clearFormatting = Formatting.strip(line);
if (line.contains("Fuel: ")) {
if (clearFormatting != null) {
String clear = Pattern.compile("[^0-9 /]").matcher(clearFormatting).replaceAll("").trim();
String[] split = clear.split("/");
current = Integer.parseInt(split[0]);
max = Integer.parseInt(split[1]) * 1000;
return new Durability(current, max);
return IntIntPair.of(current, max);
}
} else if (line.contains("uses.")) {
if (clearFormatting != null) {
Expand All @@ -138,7 +135,7 @@ public static Durability getDurability(@NotNull ItemStack stack) {
current = Integer.parseInt(usesString);
max = 5000;
}
return new Durability(current, max);
return IntIntPair.of(current, max);
}
}
}
Expand All @@ -153,7 +150,4 @@ public static ItemStack getSkyblockerStack() {
throw new RuntimeException(e);
}
}

public record Durability(int current, int max) {
}
}