From f2aa1e82cc0ad999cf0e0d5886a62b62197f9ac8 Mon Sep 17 00:00:00 2001 From: fretuks Date: Tue, 19 May 2026 23:58:54 +0200 Subject: [PATCH] extend unlock logic to support multi-node unlock plans and update version number --- gradle.properties | 2 +- .../skillengine/capability/PlayerSkillData.java | 12 ++++++++---- .../skillengine/capability/PlayerSkillProvider.java | 2 +- .../capability/SkillEngineCapabilities.java | 4 ++-- .../fretux/skillengine/client/ClientKeybinds.java | 4 ++++ .../skillengine/client/SkilltreeClientState.java | 8 ++++++-- .../network/ServerboundActivateAbilityPacket.java | 2 ++ .../network/ServerboundBindAbilityPacket.java | 10 +++++++--- .../skillengine/skilltree/AbilityNodeLoader.java | 6 +++--- .../skillengine/skilltree/SkillNodeLoader.java | 10 +++++----- 10 files changed, 39 insertions(+), 21 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5a58832..decb107 100644 --- a/gradle.properties +++ b/gradle.properties @@ -48,7 +48,7 @@ mod_name=Fretux's Skill Engine # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=All Rights Reserved # The mod version. See https://semver.org/ -mod_version=1.3.2 +mod_version=1.3.3 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/net/fretux/skillengine/capability/PlayerSkillData.java b/src/main/java/net/fretux/skillengine/capability/PlayerSkillData.java index 1daab0d..40e56c8 100644 --- a/src/main/java/net/fretux/skillengine/capability/PlayerSkillData.java +++ b/src/main/java/net/fretux/skillengine/capability/PlayerSkillData.java @@ -12,6 +12,7 @@ import net.minecraft.server.level.ServerPlayer; import java.util.HashMap; import java.util.HashSet; +import java.util.Arrays; import java.util.Map; import java.util.Set; @@ -182,25 +183,28 @@ public class PlayerSkillData { unlockedNodes.clear(); unlockedAbilities.clear(); activeTags.clear(); + Arrays.fill(abilitySlots, null); + Arrays.fill(abilityCooldowns, 0); + tagCooldowns.clear(); ListTag nodeList = tag.getList("UnlockedNodes", Tag.TAG_COMPOUND); for (Tag t : nodeList) { - ResourceLocation id = new ResourceLocation(((CompoundTag) t).getString("Id")); + ResourceLocation id = ResourceLocation.parse(((CompoundTag) t).getString("Id")); unlockedNodes.add(id); SkillNode node = SkillNodeRegistry.get(id); if (node != null) activeTags.addAll(node.getTags()); } ListTag tagList = tag.getList("ActiveTags", Tag.TAG_COMPOUND); for (Tag t : tagList) { - activeTags.add(new ResourceLocation(((CompoundTag) t).getString("Tag"))); + activeTags.add(ResourceLocation.parse(((CompoundTag) t).getString("Tag"))); } ListTag slots = tag.getList("AbilitySlots", Tag.TAG_COMPOUND); for (int i = 0; i < 3 && i < slots.size(); i++) { String id = slots.getCompound(i).getString("Id"); - abilitySlots[i] = id.isEmpty() ? null : new ResourceLocation(id); + abilitySlots[i] = id.isEmpty() ? null : ResourceLocation.parse(id); } ListTag abilityList = tag.getList("UnlockedAbilities", Tag.TAG_COMPOUND); for (Tag t : abilityList) { - unlockedAbilities.add(new ResourceLocation(((CompoundTag) t).getString("Id"))); + unlockedAbilities.add(ResourceLocation.parse(((CompoundTag) t).getString("Id"))); } ListTag cdList = tag.getList("AbilityCooldowns", Tag.TAG_COMPOUND); for (int i = 0; i < abilityCooldowns.length && i < cdList.size(); i++) { diff --git a/src/main/java/net/fretux/skillengine/capability/PlayerSkillProvider.java b/src/main/java/net/fretux/skillengine/capability/PlayerSkillProvider.java index 3af4c5b..9f24a07 100644 --- a/src/main/java/net/fretux/skillengine/capability/PlayerSkillProvider.java +++ b/src/main/java/net/fretux/skillengine/capability/PlayerSkillProvider.java @@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class PlayerSkillProvider implements ICapabilityProvider, ICapabilitySerializable { - public static final ResourceLocation ID = new ResourceLocation("skillengine", "player_skill_data"); + public static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath("skillengine", "player_skill_data"); private final PlayerSkillData backend = new PlayerSkillData(); private final LazyOptional optional = LazyOptional.of(() -> backend); diff --git a/src/main/java/net/fretux/skillengine/capability/SkillEngineCapabilities.java b/src/main/java/net/fretux/skillengine/capability/SkillEngineCapabilities.java index fef46db..8331eb2 100644 --- a/src/main/java/net/fretux/skillengine/capability/SkillEngineCapabilities.java +++ b/src/main/java/net/fretux/skillengine/capability/SkillEngineCapabilities.java @@ -22,9 +22,9 @@ public class SkillEngineCapabilities { if (event.getObject() instanceof Player) { SkillEngine.LOGGER.info("Attaching PlayerSkillData capability"); event.addCapability( - new ResourceLocation(SkillEngine.MODID, "player_skill_data"), + ResourceLocation.fromNamespaceAndPath(SkillEngine.MODID, "player_skill_data"), new PlayerSkillProvider() ); } } -} \ No newline at end of file +} diff --git a/src/main/java/net/fretux/skillengine/client/ClientKeybinds.java b/src/main/java/net/fretux/skillengine/client/ClientKeybinds.java index 91b2f11..d1fd013 100644 --- a/src/main/java/net/fretux/skillengine/client/ClientKeybinds.java +++ b/src/main/java/net/fretux/skillengine/client/ClientKeybinds.java @@ -23,5 +23,9 @@ public class ClientKeybinds { "key.categories.ui" ); event.register(OPEN_ABILITIES); + + event.register(AbilityKeybindHandler.ABILITY_1); + event.register(AbilityKeybindHandler.ABILITY_2); + event.register(AbilityKeybindHandler.ABILITY_3); } } diff --git a/src/main/java/net/fretux/skillengine/client/SkilltreeClientState.java b/src/main/java/net/fretux/skillengine/client/SkilltreeClientState.java index 7beb2d8..037bcfb 100644 --- a/src/main/java/net/fretux/skillengine/client/SkilltreeClientState.java +++ b/src/main/java/net/fretux/skillengine/client/SkilltreeClientState.java @@ -18,11 +18,15 @@ public class SkilltreeClientState { private static final int[] clientCooldowns = new int[3]; public static void updateCooldown(int slot, int cd) { - clientCooldowns[slot - 1] = cd; + int index = slot - 1; + if (index < 0 || index >= clientCooldowns.length) return; + clientCooldowns[index] = Math.max(0, cd); } public static int getClientCooldown(int slot) { - return clientCooldowns[slot - 1]; + int index = slot - 1; + if (index < 0 || index >= clientCooldowns.length) return 0; + return clientCooldowns[index]; } public static void unlockNode(ResourceLocation id) { diff --git a/src/main/java/net/fretux/skillengine/network/ServerboundActivateAbilityPacket.java b/src/main/java/net/fretux/skillengine/network/ServerboundActivateAbilityPacket.java index cf4294d..91be9e3 100644 --- a/src/main/java/net/fretux/skillengine/network/ServerboundActivateAbilityPacket.java +++ b/src/main/java/net/fretux/skillengine/network/ServerboundActivateAbilityPacket.java @@ -34,9 +34,11 @@ public class ServerboundActivateAbilityPacket { if (player == null) return; player.getCapability(SkillEngineCapabilities.PLAYER_SKILLS).ifPresent(data -> { + if (msg.slot < 1 || msg.slot > 3) return; ResourceLocation abilityId = data.getAbilityInSlot(msg.slot); if (abilityId == null) return; + if (!data.isAbilityUnlocked(abilityId)) return; AbilityNode ability = AbilityNodeRegistry.get(abilityId); if (ability == null) return; diff --git a/src/main/java/net/fretux/skillengine/network/ServerboundBindAbilityPacket.java b/src/main/java/net/fretux/skillengine/network/ServerboundBindAbilityPacket.java index 59b4248..4185071 100644 --- a/src/main/java/net/fretux/skillengine/network/ServerboundBindAbilityPacket.java +++ b/src/main/java/net/fretux/skillengine/network/ServerboundBindAbilityPacket.java @@ -1,6 +1,7 @@ package net.fretux.skillengine.network; import net.fretux.skillengine.capability.SkillEngineCapabilities; +import net.fretux.skillengine.skilltree.AbilityNodeRegistry; import net.minecraft.server.level.ServerPlayer; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; @@ -32,9 +33,12 @@ public class ServerboundBindAbilityPacket { ServerPlayer player = ctx.get().getSender(); if (player == null) return; - player.getCapability(SkillEngineCapabilities.PLAYER_SKILLS).ifPresent(data -> - data.bindAbility(msg.slot, msg.abilityId) - ); + player.getCapability(SkillEngineCapabilities.PLAYER_SKILLS).ifPresent(data -> { + if (msg.slot < 1 || msg.slot > 3) return; + if (AbilityNodeRegistry.get(msg.abilityId) == null) return; + if (!data.isAbilityUnlocked(msg.abilityId)) return; + data.bindAbility(msg.slot, msg.abilityId); + }); PacketHandler.syncSkillsTo(player); }); ctx.get().setPacketHandled(true); diff --git a/src/main/java/net/fretux/skillengine/skilltree/AbilityNodeLoader.java b/src/main/java/net/fretux/skillengine/skilltree/AbilityNodeLoader.java index 0d7560d..55bf749 100644 --- a/src/main/java/net/fretux/skillengine/skilltree/AbilityNodeLoader.java +++ b/src/main/java/net/fretux/skillengine/skilltree/AbilityNodeLoader.java @@ -48,11 +48,11 @@ public class AbilityNodeLoader extends SimpleJsonResourceReloadListener { float y = pos.get("y").getAsFloat(); List links = new ArrayList<>(); obj.getAsJsonArray("links").forEach(e -> - links.add(new ResourceLocation(e.getAsString()))); + links.add(ResourceLocation.parse(e.getAsString()))); List tags = new ArrayList<>(); obj.getAsJsonArray("tags").forEach(e -> - tags.add(new ResourceLocation(e.getAsString()))); - ResourceLocation icon = new ResourceLocation(obj.get("icon").getAsString()); + tags.add(ResourceLocation.parse(e.getAsString()))); + ResourceLocation icon = ResourceLocation.parse(obj.get("icon").getAsString()); int cooldown = obj.has("cooldown") ? obj.get("cooldown").getAsInt() : 0; AbilityNode node = new AbilityNode(id, title, description, x, y, links, tags, icon, cooldown); AbilityNodeRegistry.put(node); diff --git a/src/main/java/net/fretux/skillengine/skilltree/SkillNodeLoader.java b/src/main/java/net/fretux/skillengine/skilltree/SkillNodeLoader.java index 6c0953a..0821a73 100644 --- a/src/main/java/net/fretux/skillengine/skilltree/SkillNodeLoader.java +++ b/src/main/java/net/fretux/skillengine/skilltree/SkillNodeLoader.java @@ -40,7 +40,7 @@ public class SkillNodeLoader extends SimpleJsonResourceReloadListener { jsons.forEach((id, element) -> { JsonObject obj = element.getAsJsonObject(); ResourceLocation nodeId = obj.has("id") - ? new ResourceLocation(obj.get("id").getAsString()) + ? ResourceLocation.parse(obj.get("id").getAsString()) : id; String title = obj.get("title").getAsString(); String description = obj.get("description").getAsString(); @@ -50,11 +50,11 @@ public class SkillNodeLoader extends SimpleJsonResourceReloadListener { float y = pos.get("y").getAsFloat(); List links = new ArrayList<>(); obj.getAsJsonArray("links").forEach(e -> - links.add(new ResourceLocation(e.getAsString()))); + links.add(ResourceLocation.parse(e.getAsString()))); List tags = new ArrayList<>(); obj.getAsJsonArray("tags").forEach(e -> - tags.add(new ResourceLocation(e.getAsString()))); - ResourceLocation icons = new ResourceLocation(obj.get("icons").getAsString()); + tags.add(ResourceLocation.parse(e.getAsString()))); + ResourceLocation icons = ResourceLocation.parse(obj.get("icons").getAsString()); Map prereqAttributes = new HashMap<>(); if (obj.has("prerequisites")) { JsonObject prereqObj = obj.getAsJsonObject("prerequisites"); @@ -65,7 +65,7 @@ public class SkillNodeLoader extends SimpleJsonResourceReloadListener { List exclusiveWith = new ArrayList<>(); if (obj.has("exclusive_with")) { obj.getAsJsonArray("exclusive_with").forEach(e -> - exclusiveWith.add(new ResourceLocation(e.getAsString()))); + exclusiveWith.add(ResourceLocation.parse(e.getAsString()))); } SkillNode node = new SkillNode( nodeId,