Skip to content

Commit

Permalink
Merge pull request #332 from Grayray75/item-cooldown
Browse files Browse the repository at this point in the history
Item cooldown display
  • Loading branch information
LifeIsAParadox authored Oct 9, 2023
2 parents 0c93811 + 1618ac6 commit a07b748
Show file tree
Hide file tree
Showing 15 changed files with 250 additions and 16 deletions.
2 changes: 2 additions & 0 deletions src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.gson.GsonBuilder;
import me.xmrvizzy.skyblocker.config.SkyblockerConfigManager;
import me.xmrvizzy.skyblocker.skyblock.*;
import me.xmrvizzy.skyblocker.skyblock.item.ItemCooldowns;
import me.xmrvizzy.skyblocker.skyblock.dungeon.*;
import me.xmrvizzy.skyblocker.skyblock.dungeon.secrets.DungeonSecrets;
import me.xmrvizzy.skyblocker.skyblock.dwarven.DwarvenHud;
Expand Down Expand Up @@ -78,6 +79,7 @@ public void onInitializeClient() {
Relics.init();
BackpackPreview.init();
QuickNav.init();
ItemCooldowns.init();
DwarvenHud.init();
ChatMessageListener.init();
Shortcuts.init();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ public static class General {
@SerialEntry
public FairySouls fairySouls = new FairySouls();

@SerialEntry
public ItemCooldown itemCooldown = new ItemCooldown();

@SerialEntry
public Shortcuts shortcuts = new Shortcuts();

Expand Down Expand Up @@ -313,6 +316,11 @@ public static class FairySouls {
public boolean highlightOnlyNearbySouls = false;
}

public static class ItemCooldown {
@SerialEntry
public boolean enableItemCooldowns = true;
}

public static class Shortcuts {
@SerialEntry
public boolean enableShortcuts = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,19 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig
.build())
.build())

//Item Cooldown
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.general.itemCooldown"))
.collapsed(true)
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.general.itemCooldown.enableItemCooldowns"))
.binding(defaults.general.itemCooldown.enableItemCooldowns,
() -> config.general.itemCooldown.enableItemCooldowns,
newValue -> config.general.itemCooldown.enableItemCooldowns = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
.build())

//Shortcuts
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.general.shortcuts"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package me.xmrvizzy.skyblocker.events;

import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

// Fabric API currently doesn't have an event for this
public class ClientPlayerBlockBreakEvent {
public static final Event<AfterBlockBreak> AFTER = EventFactory.createArrayBacked(AfterBlockBreak.class,
(listeners) -> (world, player, pos, state) -> {
for (AfterBlockBreak listener : listeners) {
listener.afterBlockBreak(world, player, pos, state);
}
});

@FunctionalInterface
public interface AfterBlockBreak {
void afterBlockBreak(World world, PlayerEntity player, BlockPos pos, BlockState state);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.xmrvizzy.skyblocker.utils;
package me.xmrvizzy.skyblocker.events;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package me.xmrvizzy.skyblocker.mixin;

import me.xmrvizzy.skyblocker.events.ClientPlayerBlockBreakEvent;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerInteractionManager;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

@Mixin(ClientPlayerInteractionManager.class)
public class ClientPlayerInteractionManagerMixin {
@Shadow
@Final
private MinecraftClient client;

@Inject(method = "breakBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/Block;onBroken(Lnet/minecraft/world/WorldAccess;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)V"), locals = LocalCapture.CAPTURE_FAILHARD)
private void skyblocker$onBlockBroken(BlockPos pos, CallbackInfoReturnable<Boolean> cir, World world, BlockState blockState) {
ClientPlayerBlockBreakEvent.AFTER.invoker().afterBlockBreak(world, this.client.player, pos, blockState);
}
}
12 changes: 9 additions & 3 deletions src/main/java/me/xmrvizzy/skyblocker/mixin/DrawContextMixin.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package me.xmrvizzy.skyblocker.mixin;

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
import com.mojang.blaze3d.systems.RenderSystem;

import dev.cbyrne.betterinject.annotations.Arg;
import dev.cbyrne.betterinject.annotations.Inject;
import me.xmrvizzy.skyblocker.config.SkyblockerConfigManager;
import me.xmrvizzy.skyblocker.skyblock.item.AttributeShards;
import me.xmrvizzy.skyblocker.skyblock.item.ItemCooldowns;
import me.xmrvizzy.skyblocker.utils.ItemUtils;
import me.xmrvizzy.skyblocker.utils.Utils;
import net.minecraft.client.font.TextRenderer;
Expand All @@ -18,7 +19,6 @@
import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.ColorHelper;

import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
Expand Down Expand Up @@ -130,4 +130,10 @@ public abstract class DrawContextMixin {
}
}
}
}

@ModifyExpressionValue(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/ItemCooldownManager;getCooldownProgress(Lnet/minecraft/item/Item;F)F"))
private float skyblocker$modifyItemCooldown(float cooldownProgress, @Local ItemStack stack) {
return Utils.isOnSkyblock() && ItemCooldowns.isOnCooldown(stack) ? ItemCooldowns.getItemCooldownEntry(stack).getRemainingCooldownPercent() : cooldownProgress;
}
}
25 changes: 23 additions & 2 deletions src/main/java/me/xmrvizzy/skyblocker/mixin/InGameHudMixin.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package me.xmrvizzy.skyblocker.mixin;

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.sugar.Local;
import me.xmrvizzy.skyblocker.SkyblockerMod;
import me.xmrvizzy.skyblocker.config.SkyblockerConfigManager;
import me.xmrvizzy.skyblocker.skyblock.FancyStatusBars;
import me.xmrvizzy.skyblocker.skyblock.HotbarSlotLock;
import me.xmrvizzy.skyblocker.skyblock.item.ItemCooldowns;
import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonMap;
import me.xmrvizzy.skyblocker.skyblock.item.ItemRarityBackgrounds;
import me.xmrvizzy.skyblocker.utils.Utils;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
Expand All @@ -34,6 +39,10 @@ public abstract class InGameHudMixin {
@Shadow
private int scaledWidth;

@Shadow
@Final
private MinecraftClient client;

@Inject(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/DrawContext;IIFLnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V", ordinal = 0))
public void skyblocker$renderHotbarItemLockOrRarityBg(float tickDelta, DrawContext context, CallbackInfo ci, @Local(ordinal = 4, name = "m") int index, @Local(ordinal = 5, name = "n") int x, @Local(ordinal = 6, name = "o") int y, @Local PlayerEntity player) {
if (Utils.isOnSkyblock()) {
Expand Down Expand Up @@ -64,9 +73,21 @@ public abstract class InGameHudMixin {
if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.bars.enableBars && !Utils.isInTheRift())
ci.cancel();
}

@Inject(method = "renderStatusEffectOverlay", at = @At("HEAD"), cancellable = true)
private void skyblocker$dontRenderStatusEffects(CallbackInfo ci) {
if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.hideStatusEffectOverlay) ci.cancel();
}
}

@ModifyExpressionValue(method = "renderCrosshair", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getAttackCooldownProgress(F)F"))
private float skyblocker$modifyAttackIndicatorCooldown(float cooldownProgress) {
if (Utils.isOnSkyblock() && client.player != null) {
ItemStack stack = client.player.getMainHandStack();
if (ItemCooldowns.isOnCooldown(stack)) {
return ItemCooldowns.getItemCooldownEntry(stack).getRemainingCooldownPercent();
}
}

return cooldownProgress;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import me.xmrvizzy.skyblocker.config.SkyblockerConfigManager;
import me.xmrvizzy.skyblocker.utils.SkyblockEvents;
import me.xmrvizzy.skyblocker.events.SkyblockEvents;
import me.xmrvizzy.skyblocker.utils.Utils;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
Expand Down
115 changes: 115 additions & 0 deletions src/main/java/me/xmrvizzy/skyblocker/skyblock/item/ItemCooldowns.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package me.xmrvizzy.skyblocker.skyblock.item;

import com.google.common.collect.ImmutableList;
import me.xmrvizzy.skyblocker.config.SkyblockerConfigManager;
import me.xmrvizzy.skyblocker.events.ClientPlayerBlockBreakEvent;
import me.xmrvizzy.skyblocker.utils.ItemUtils;
import net.fabricmc.fabric.api.event.player.UseItemCallback;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

import java.util.HashMap;
import java.util.Map;

public class ItemCooldowns {
private static final String JUNGLE_AXE_ID = "JUNGLE_AXE";
private static final String TREECAPITATOR_ID = "TREECAPITATOR_AXE";
private static final String GRAPPLING_HOOK_ID = "GRAPPLING_HOOK";
private static final ImmutableList<String> BAT_ARMOR_IDS = ImmutableList.of("BAT_PERSON_HELMET", "BAT_PERSON_CHESTPLATE", "BAT_PERSON_LEGGINGS", "BAT_PERSON_BOOTS");

private static final Map<String, CooldownEntry> ITEM_COOLDOWNS = new HashMap<>();

public static void init() {
ClientPlayerBlockBreakEvent.AFTER.register(ItemCooldowns::afterBlockBreak);
UseItemCallback.EVENT.register(ItemCooldowns::onItemInteract);
}

public static void afterBlockBreak(World world, PlayerEntity player, BlockPos pos, BlockState state) {
if (!SkyblockerConfigManager.get().general.itemCooldown.enableItemCooldowns) return;

String usedItemId = ItemUtils.getItemId(player.getMainHandStack());
if (usedItemId == null) return;

if (state.isIn(BlockTags.LOGS)) {
if (usedItemId.equals(JUNGLE_AXE_ID)) {
if (!isOnCooldown(JUNGLE_AXE_ID)) {
ITEM_COOLDOWNS.put(JUNGLE_AXE_ID, new CooldownEntry(2000));
}
} else if (usedItemId.equals(TREECAPITATOR_ID)) {
if (!isOnCooldown(TREECAPITATOR_ID)) {
ITEM_COOLDOWNS.put(TREECAPITATOR_ID, new CooldownEntry(2000));
}
}
}
}

private static TypedActionResult<ItemStack> onItemInteract(PlayerEntity player, World world, Hand hand) {
if (!SkyblockerConfigManager.get().general.itemCooldown.enableItemCooldowns) return TypedActionResult.pass(ItemStack.EMPTY);

String usedItemId = ItemUtils.getItemId(player.getMainHandStack());
if (usedItemId != null && usedItemId.equals(GRAPPLING_HOOK_ID) && player.fishHook != null) {
if (!isOnCooldown(GRAPPLING_HOOK_ID) && !isWearingBatArmor(player)) {
ITEM_COOLDOWNS.put(GRAPPLING_HOOK_ID, new CooldownEntry(2000));
}
}

return TypedActionResult.pass(ItemStack.EMPTY);
}

public static boolean isOnCooldown(ItemStack itemStack) {
return isOnCooldown(ItemUtils.getItemId(itemStack));
}

private static boolean isOnCooldown(String itemId) {
if (ITEM_COOLDOWNS.containsKey(itemId)) {
CooldownEntry cooldownEntry = ITEM_COOLDOWNS.get(itemId);
if (cooldownEntry.isOnCooldown()) {
return true;
} else {
ITEM_COOLDOWNS.remove(itemId);
return false;
}
}

return false;
}

public static CooldownEntry getItemCooldownEntry(ItemStack itemStack) {
return ITEM_COOLDOWNS.get(ItemUtils.getItemId(itemStack));
}

private static boolean isWearingBatArmor(PlayerEntity player) {
for (ItemStack stack : player.getArmorItems()) {
String itemId = ItemUtils.getItemId(stack);
if (!BAT_ARMOR_IDS.contains(itemId)) {
return false;
}
}
return true;
}

public record CooldownEntry(int cooldown, long startTime) {
public CooldownEntry(int cooldown) {
this(cooldown, System.currentTimeMillis());
}

public boolean isOnCooldown() {
return (this.startTime + this.cooldown) > System.currentTimeMillis();
}

public long getRemainingCooldown() {
long time = (this.startTime + this.cooldown) - System.currentTimeMillis();
return Math.max(time, 0);
}

public float getRemainingCooldownPercent() {
return this.isOnCooldown() ? (float) this.getRemainingCooldown() / cooldown : 0.0f;
}
}
}
15 changes: 15 additions & 0 deletions src/main/java/me/xmrvizzy/skyblocker/utils/ItemUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.StringNbtReader;
import net.minecraft.text.Text;

Expand Down Expand Up @@ -40,4 +41,18 @@ public static ItemStack getSkyblockerStack() {
throw new RuntimeException(e);
}
}

public static String getItemId(ItemStack itemStack) {
if (itemStack == null) return null;

NbtCompound nbt = itemStack.getNbt();
if (nbt != null && nbt.contains("ExtraAttributes")) {
NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes");
if (extraAttributes.contains("id")) {
return extraAttributes.getString("id");
}
}

return null;
}
}
1 change: 1 addition & 0 deletions src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.xmrvizzy.skyblocker.events.SkyblockEvents;
import me.xmrvizzy.skyblocker.skyblock.item.PriceInfoTooltip;
import me.xmrvizzy.skyblocker.skyblock.rift.TheRift;
import me.xmrvizzy.skyblocker.utils.scheduler.MessageScheduler;
Expand Down
Loading

0 comments on commit a07b748

Please sign in to comment.