package net.fretux.skillengine.client; import net.fretux.skillengine.SkillEngine; import net.fretux.skillengine.capability.PlayerSkillData; import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; import java.util.Arrays; import java.util.HashSet; import java.util.Set; public class SkilltreeClientState { private static final Set unlocked = new HashSet<>(); private static final Set unlockedAbilities = new HashSet<>(); private static int currentSkillPoints = 0; private static ResourceLocation[] abilitySlots = new ResourceLocation[3]; private static int[] clientCooldowns = new int[3]; public static void updateCooldown(int slot, int cd) { ensureSlot(slot); int index = slot - 1; if (index < 0 || index >= clientCooldowns.length) return; clientCooldowns[index] = Math.max(0, cd); } public static int getClientCooldown(int slot) { ensureSlot(slot); int index = slot - 1; if (index < 0 || index >= clientCooldowns.length) return 0; return clientCooldowns[index]; } public static void unlockNode(ResourceLocation id) { SkillEngine.LOGGER.info("[CLIENT] Unlocking node: {}", id); unlocked.add(id); Minecraft mc = Minecraft.getInstance(); if (mc.player != null) { mc.player.playSound(SoundEvents.EXPERIENCE_ORB_PICKUP, 1f, 1.2f); } } public static boolean isUnlocked(ResourceLocation id) { return unlocked.contains(id); } public static void setUnlocked(Iterable ids) { unlocked.clear(); for (ResourceLocation id : ids) { unlocked.add(id); } } public static void setUnlockedAbilities(Iterable abilities) { unlockedAbilities.clear(); for (ResourceLocation ability : abilities) { unlockedAbilities.add(ability); } } public static void setCurrentSkillPoints(int points) { currentSkillPoints = points; } public static int getCurrentSkillPoints() { return currentSkillPoints; } public static boolean isAbilityUnlocked(ResourceLocation id) { return unlockedAbilities.contains(id); } public static void unlockAbility(ResourceLocation id) { unlockedAbilities.add(id); } public static void bindAbilityLocal(int slot, ResourceLocation abilityId) { ensureSlot(slot); PlayerSkillData.bindHelper(slot, abilityId, abilitySlots); } public static void setAbilitySlots(ResourceLocation[] slots) { abilitySlots = new ResourceLocation[slots != null ? slots.length : 3]; clientCooldowns = Arrays.copyOf(clientCooldowns, abilitySlots.length); for (int i = 0; i < abilitySlots.length; i++) { abilitySlots[i] = (slots != null && i < slots.length) ? slots[i] : null; } } public static ResourceLocation getAbilityInSlot(int slot) { ensureSlot(slot); int index = slot - 1; if (index < 0 || index >= abilitySlots.length) return null; return abilitySlots[index]; } public static int getSlotOfAbility(ResourceLocation abilityId) { if (abilityId == null) return -1; for (int i = 0; i < abilitySlots.length; i++) { if (abilityId.equals(abilitySlots[i])) return i + 1; } return -1; } public static ResourceLocation[] getAbilitySlots() { return Arrays.copyOf(abilitySlots, abilitySlots.length); } private static void ensureSlot(int slot) { if (slot <= abilitySlots.length) return; abilitySlots = Arrays.copyOf(abilitySlots, slot); clientCooldowns = Arrays.copyOf(clientCooldowns, slot); } }