Add client-side ability cooldowns, sync, and GUI updates

This commit is contained in:
2025-12-07 22:54:45 +01:00
parent d4ad08a35a
commit c6cf504f67
11 changed files with 310 additions and 7 deletions
@@ -0,0 +1,38 @@
package net.fretux.skillengine.client;
import net.fretux.skillengine.skilltree.AbilityNode;
import net.fretux.skillengine.skilltree.AbilityNodeRegistry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.client.event.RenderGuiEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber
public class AbilityHudOverlay {
@SubscribeEvent
public static void render(RenderGuiEvent.Post event) {
Minecraft mc = Minecraft.getInstance();
if (mc.player == null) return;
int xStart = event.getGuiGraphics().guiWidth() - 80;
int yStart = 10;
for (int slot = 1; slot <= 3; slot++) {
var abilityId = SkilltreeClientState.getAbilityInSlot(slot);
if (abilityId == null) continue;
AbilityNode ability = AbilityNodeRegistry.get(abilityId);
if (ability == null) continue;
int cd = SkilltreeClientState.getClientCooldown(slot);
ResourceLocation icon = ability.getIcon();
GuiGraphics gfx = event.getGuiGraphics();
gfx.blit(icon, xStart, yStart, 0, 0, 16, 16, 16, 16);
if (cd > 0) {
String text = String.valueOf(cd / 20);
gfx.drawString(mc.font, text, xStart + 20, yStart + 4, 0xFF5555);
}
gfx.drawString(mc.font, "Ability " + slot, xStart + 40, yStart + 4, 0xFFFFFF);
yStart += 20;
}
}
}
@@ -0,0 +1,49 @@
package net.fretux.skillengine.client;
import com.mojang.blaze3d.platform.InputConstants;
import net.fretux.skillengine.network.PacketHandler;
import net.fretux.skillengine.network.ServerboundActivateAbilityPacket;
import net.minecraft.client.KeyMapping;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.settings.KeyConflictContext;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.lwjgl.glfw.GLFW;
@Mod.EventBusSubscriber
public class AbilityKeybindHandler {
public static final KeyMapping ABILITY_1 = new KeyMapping(
"key.skillengine.ability1", KeyConflictContext.IN_GAME,
InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_Y, "key.categories.gameplay"
);
public static final KeyMapping ABILITY_2 = new KeyMapping(
"key.skillengine.ability2", KeyConflictContext.IN_GAME,
InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_X, "key.categories.gameplay"
);
public static final KeyMapping ABILITY_3 = new KeyMapping(
"key.skillengine.ability3", KeyConflictContext.IN_GAME,
InputConstants.Type.KEYSYM, GLFW.GLFW_KEY_C, "key.categories.gameplay"
);
@SubscribeEvent
public static void onInput(InputEvent.Key event) {
if (ABILITY_1.consumeClick()) {
if (SkilltreeClientState.getClientCooldown(1) <= 0) {
PacketHandler.CHANNEL.sendToServer(new ServerboundActivateAbilityPacket(1));
}
}
if (ABILITY_2.consumeClick()) {
if (SkilltreeClientState.getClientCooldown(2) <= 0) {
PacketHandler.CHANNEL.sendToServer(new ServerboundActivateAbilityPacket(2));
}
}
if (ABILITY_3.consumeClick()) {
if (SkilltreeClientState.getClientCooldown(3) <= 0) {
PacketHandler.CHANNEL.sendToServer(new ServerboundActivateAbilityPacket(3));
}
}
}
}
@@ -0,0 +1,22 @@
package net.fretux.skillengine.client;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.fretux.skillengine.SkillEngine;
@Mod.EventBusSubscriber(modid = SkillEngine.MODID, value = Dist.CLIENT)
public class ClientCooldownTicker {
@SubscribeEvent
public static void onClientTick(TickEvent.ClientTickEvent event) {
if (event.phase != TickEvent.Phase.END) return;
for (int i = 0; i < 3; i++) {
int cd = SkilltreeClientState.getClientCooldown(i + 1);
if (cd > 0) {
SkilltreeClientState.updateCooldown(i + 1, cd - 1);
}
}
}
}
@@ -17,6 +17,15 @@ public class SkilltreeClientState {
private static final Set<ResourceLocation> unlockedAbilities = new HashSet<>();
private static int currentSkillPoints = 0;
private static final ResourceLocation[] abilitySlots = new ResourceLocation[3];
private static final int[] clientCooldowns = new int[3];
public static void updateCooldown(int slot, int cd) {
clientCooldowns[slot - 1] = cd;
}
public static int getClientCooldown(int slot) {
return clientCooldowns[slot - 1];
}
public static void unlockNode(ResourceLocation id) {
SkillEngine.LOGGER.info("[CLIENT] Unlocking node: {}", id);
@@ -246,6 +246,14 @@ public class SkilltreeScreen extends Screen {
);
}));
}
if (!hoveredNode.getExclusiveWith().isEmpty()) {
tooltip.add(Component.literal("Mutually Exclusive with:")
.withStyle(ChatFormatting.RED));
for (ResourceLocation ex : hoveredNode.getExclusiveWith()) {
tooltip.add(Component.literal(" - " + ex.toString())
.withStyle(ChatFormatting.RED));
}
}
gfx.renderComponentTooltip(font, tooltip, mouseX, mouseY);
}