package net.minecraft.world.item; import com.google.common.collect.Maps; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.item.component.UseCooldown; public class ItemCooldowns { private final Map cooldowns = Maps.newHashMap(); private int tickCount; public boolean isOnCooldown(ItemStack stack) { return this.getCooldownPercent(stack, 0.0F) > 0.0F; } public float getCooldownPercent(ItemStack stack, float partialTick) { ResourceLocation resourceLocation = this.getCooldownGroup(stack); ItemCooldowns.CooldownInstance cooldownInstance = (ItemCooldowns.CooldownInstance)this.cooldowns.get(resourceLocation); if (cooldownInstance != null) { float f = cooldownInstance.endTime - cooldownInstance.startTime; float g = cooldownInstance.endTime - (this.tickCount + partialTick); return Mth.clamp(g / f, 0.0F, 1.0F); } else { return 0.0F; } } public void tick() { this.tickCount++; if (!this.cooldowns.isEmpty()) { Iterator> iterator = this.cooldowns.entrySet().iterator(); while (iterator.hasNext()) { Entry entry = (Entry)iterator.next(); if (((ItemCooldowns.CooldownInstance)entry.getValue()).endTime <= this.tickCount) { iterator.remove(); this.onCooldownEnded((ResourceLocation)entry.getKey()); } } } } public ResourceLocation getCooldownGroup(ItemStack stack) { UseCooldown useCooldown = stack.get(DataComponents.USE_COOLDOWN); ResourceLocation resourceLocation = BuiltInRegistries.ITEM.getKey(stack.getItem()); return useCooldown == null ? resourceLocation : (ResourceLocation)useCooldown.cooldownGroup().orElse(resourceLocation); } public void addCooldown(ItemStack stack, int cooldown) { this.addCooldown(this.getCooldownGroup(stack), cooldown); } public void addCooldown(ResourceLocation group, int cooldown) { this.cooldowns.put(group, new ItemCooldowns.CooldownInstance(this.tickCount, this.tickCount + cooldown)); this.onCooldownStarted(group, cooldown); } public void removeCooldown(ResourceLocation group) { this.cooldowns.remove(group); this.onCooldownEnded(group); } protected void onCooldownStarted(ResourceLocation group, int cooldown) { } protected void onCooldownEnded(ResourceLocation group) { } record CooldownInstance(int startTime, int endTime) { } }