Implement rebinding, Translation support and small adjustments to balance
This commit is contained in:
@@ -22,6 +22,12 @@ public class StatsScreen extends Screen {
|
|||||||
private int topPos;
|
private int topPos;
|
||||||
|
|
||||||
private final Minecraft mc = Minecraft.getInstance();
|
private final Minecraft mc = Minecraft.getInstance();
|
||||||
|
private final Map<String, Button> plusButtons = new HashMap<>();
|
||||||
|
private String hoveredAttributeKey = null;
|
||||||
|
|
||||||
|
public StatsScreen() {
|
||||||
|
super(Component.literal("Ascend Stats"));
|
||||||
|
}
|
||||||
|
|
||||||
private static final String[] ATTRIBUTES = new String[]{
|
private static final String[] ATTRIBUTES = new String[]{
|
||||||
"strength", "agility", "fortitude", "intelligence",
|
"strength", "agility", "fortitude", "intelligence",
|
||||||
@@ -29,49 +35,13 @@ public class StatsScreen extends Screen {
|
|||||||
"light_scaling", "medium_scaling", "heavy_scaling", "magic_scaling"
|
"light_scaling", "medium_scaling", "heavy_scaling", "magic_scaling"
|
||||||
};
|
};
|
||||||
|
|
||||||
private final Map<String, Button> plusButtons = new HashMap<>();
|
// Use translation keys for attribute labels and tooltips
|
||||||
|
|
||||||
// --- Tooltips for attributes ---
|
|
||||||
private static final Map<String, Component> ATTRIBUTE_TOOLTIPS = new HashMap<>();
|
private static final Map<String, Component> ATTRIBUTE_TOOLTIPS = new HashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ATTRIBUTE_TOOLTIPS.put("strength", Component.literal(
|
for (String key : ATTRIBUTES) {
|
||||||
"Strength: Increases melee damage, knockback and armor penetration."
|
ATTRIBUTE_TOOLTIPS.put(key, Component.translatable("ascend.attribute." + key + ".desc"));
|
||||||
));
|
}
|
||||||
ATTRIBUTE_TOOLTIPS.put("agility", Component.literal(
|
|
||||||
"Agility: Increases movement speed and mobility."
|
|
||||||
));
|
|
||||||
ATTRIBUTE_TOOLTIPS.put("fortitude", Component.literal(
|
|
||||||
"Fortitude: Increases max health and knockback resistance."
|
|
||||||
));
|
|
||||||
ATTRIBUTE_TOOLTIPS.put("intelligence", Component.literal(
|
|
||||||
"Intelligence: Boosts mana, spell power, mana regen & cooldown reduction (with Iron's Spellbooks)."
|
|
||||||
));
|
|
||||||
ATTRIBUTE_TOOLTIPS.put("willpower", Component.literal(
|
|
||||||
"Willpower: Reduces sanity drain and improves stamina/tempo in harsh conditions."
|
|
||||||
));
|
|
||||||
ATTRIBUTE_TOOLTIPS.put("charisma", Component.literal(
|
|
||||||
"Charisma: Increases max mana and improves trade deals."
|
|
||||||
));
|
|
||||||
ATTRIBUTE_TOOLTIPS.put("light_scaling", Component.literal(
|
|
||||||
"Light Scaling: Increases damage with light weapons that scale with this stat."
|
|
||||||
));
|
|
||||||
ATTRIBUTE_TOOLTIPS.put("medium_scaling", Component.literal(
|
|
||||||
"Medium Scaling: Increases damage with medium weapons that scale with this stat."
|
|
||||||
));
|
|
||||||
ATTRIBUTE_TOOLTIPS.put("heavy_scaling", Component.literal(
|
|
||||||
"Heavy Scaling: Increases damage with heavy weapons that scale with this stat."
|
|
||||||
));
|
|
||||||
ATTRIBUTE_TOOLTIPS.put("magic_scaling", Component.literal(
|
|
||||||
"Magic Scaling: Increases spell power, mana regen & cooldown reduction for scaling spells."
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// which attribute label the mouse is currently over (for tooltip)
|
|
||||||
private String hoveredAttributeKey = null;
|
|
||||||
|
|
||||||
public StatsScreen() {
|
|
||||||
super(Component.literal("Ascend Stats"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -108,7 +78,8 @@ public class StatsScreen extends Screen {
|
|||||||
RenderSystem.enableBlend();
|
RenderSystem.enableBlend();
|
||||||
gui.fill(leftPos - 4, topPos - 4, leftPos + WIDTH + 4, topPos + HEIGHT + 4, 0xAA000000);
|
gui.fill(leftPos - 4, topPos - 4, leftPos + WIDTH + 4, topPos + HEIGHT + 4, 0xAA000000);
|
||||||
RenderSystem.disableBlend();
|
RenderSystem.disableBlend();
|
||||||
gui.drawCenteredString(this.font, this.title, this.width / 2, topPos + 8, 0xFFFFFF);
|
gui.drawCenteredString(this.font, Component.translatable("ascend.stats.title"), this.width / 2, topPos + 8, 0xFFFFFF);
|
||||||
|
|
||||||
hoveredAttributeKey = null;
|
hoveredAttributeKey = null;
|
||||||
if (mc.player != null) {
|
if (mc.player != null) {
|
||||||
mc.player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
mc.player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||||
@@ -116,26 +87,25 @@ public class StatsScreen extends Screen {
|
|||||||
int xp = stats.getAscendXP();
|
int xp = stats.getAscendXP();
|
||||||
int xpNext = stats.getXPToNextAscendLevel();
|
int xpNext = stats.getXPToNextAscendLevel();
|
||||||
int unspent = stats.getUnspentPoints();
|
int unspent = stats.getUnspentPoints();
|
||||||
String levelStr = "Level: " + level + "/" + 20;
|
|
||||||
gui.drawString(font, levelStr, leftPos + 10, topPos + 24, 0xFFFF55);
|
gui.drawString(font, Component.translatable("ascend.stats.level", level, 20), leftPos + 10, topPos + 24, 0xFFFF55);
|
||||||
if (level < 20) {
|
if (level < 20) {
|
||||||
String xpStr = "Ascend XP: " + xp + " / " + xpNext;
|
gui.drawString(font, Component.translatable("ascend.stats.xp", xp, xpNext), leftPos + 10, topPos + 36, 0xAAAAAA);
|
||||||
gui.drawString(font, xpStr, leftPos + 10, topPos + 36, 0xAAAAAA);
|
|
||||||
} else {
|
} else {
|
||||||
gui.drawString(font, "Ascend XP: MAX", leftPos + 10, topPos + 36, 0xAAAAAA);
|
gui.drawString(font, Component.translatable("ascend.stats.xp_max"), leftPos + 10, topPos + 36, 0xAAAAAA);
|
||||||
}
|
}
|
||||||
String ptsStr = "Unspent Points: " + unspent;
|
gui.drawString(font, Component.translatable("ascend.stats.unspent", unspent),
|
||||||
int ptsWidth = font.width(ptsStr);
|
leftPos + WIDTH - 10 - font.width("Unspent Points: " + unspent), topPos + 24, 0x55FF55);
|
||||||
gui.drawString(font, ptsStr,
|
|
||||||
leftPos + WIDTH - 10 - ptsWidth, topPos + 24, 0x55FF55);
|
|
||||||
int y = topPos + 55;
|
int y = topPos + 55;
|
||||||
for (String key : ATTRIBUTES) {
|
for (String key : ATTRIBUTES) {
|
||||||
int attrLevel = stats.getAttributeLevel(key);
|
int attrLevel = stats.getAttributeLevel(key);
|
||||||
int cost = stats.getCostToUpgrade(key);
|
int cost = stats.getCostToUpgrade(key);
|
||||||
String niceName = formatAttributeName(key);
|
Component name = Component.translatable("ascend.attribute." + key);
|
||||||
String label = niceName + ": " + attrLevel;
|
Component label = Component.translatable("ascend.attribute.display", name, attrLevel);
|
||||||
int labelX = leftPos + 10;
|
int labelX = leftPos + 10;
|
||||||
gui.drawString(font, label, labelX, y, 0xFFFFFF);
|
gui.drawString(font, label, labelX, y, 0xFFFFFF);
|
||||||
|
|
||||||
Button plus = plusButtons.get(key);
|
Button plus = plusButtons.get(key);
|
||||||
if (plus != null) {
|
if (plus != null) {
|
||||||
plus.setX(leftPos + WIDTH - 40);
|
plus.setX(leftPos + WIDTH - 40);
|
||||||
@@ -143,17 +113,19 @@ public class StatsScreen extends Screen {
|
|||||||
plus.active = (unspent >= cost);
|
plus.active = (unspent >= cost);
|
||||||
plus.setMessage(Component.literal("+" + cost));
|
plus.setMessage(Component.literal("+" + cost));
|
||||||
}
|
}
|
||||||
|
|
||||||
int labelWidth = font.width(label);
|
int labelWidth = font.width(label);
|
||||||
int labelHeight = font.lineHeight;
|
|
||||||
if (mouseX >= labelX && mouseX <= labelX + labelWidth
|
if (mouseX >= labelX && mouseX <= labelX + labelWidth
|
||||||
&& mouseY >= y && mouseY <= y + labelHeight) {
|
&& mouseY >= y && mouseY <= y + font.lineHeight) {
|
||||||
hoveredAttributeKey = key;
|
hoveredAttributeKey = key;
|
||||||
}
|
}
|
||||||
y += 16;
|
y += 16;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
super.render(gui, mouseX, mouseY, partialTicks);
|
super.render(gui, mouseX, mouseY, partialTicks);
|
||||||
|
|
||||||
if (hoveredAttributeKey != null) {
|
if (hoveredAttributeKey != null) {
|
||||||
Component tooltip = ATTRIBUTE_TOOLTIPS.get(hoveredAttributeKey);
|
Component tooltip = ATTRIBUTE_TOOLTIPS.get(hoveredAttributeKey);
|
||||||
if (tooltip != null) {
|
if (tooltip != null) {
|
||||||
@@ -162,11 +134,6 @@ public class StatsScreen extends Screen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatAttributeName(String key) {
|
|
||||||
String withSpaces = key.replace('_', ' ');
|
|
||||||
return withSpaces.substring(0, 1).toUpperCase() + withSpaces.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPauseScreen() {
|
public boolean isPauseScreen() {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package net.fretux.ascend.network;
|
package net.fretux.ascend.network;
|
||||||
|
|
||||||
import net.fretux.ascend.player.PlayerStats;
|
|
||||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||||
import net.fretux.ascend.player.StatEffects;
|
import net.fretux.ascend.player.StatEffects;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -35,13 +34,6 @@ public class ClientboundSyncStatsPacket {
|
|||||||
stats.deserializeNBT(data);
|
stats.deserializeNBT(data);
|
||||||
StatEffects.applyAll(mc.player);
|
StatEffects.applyAll(mc.player);
|
||||||
stats.deserializeNBT(data);
|
stats.deserializeNBT(data);
|
||||||
System.out.println("[CLIENT] Before sync: points="
|
|
||||||
+ player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
|
||||||
.map(PlayerStats::getUnspentPoints).orElse(-1));
|
|
||||||
stats.deserializeNBT(data);
|
|
||||||
System.out.println("[CLIENT] After sync: points="
|
|
||||||
+ player.getCapability(PlayerStatsProvider.PLAYER_STATS)
|
|
||||||
.map(PlayerStats::getUnspentPoints).orElse(-1));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ctx.get().setPacketHandled(true);
|
ctx.get().setPacketHandled(true);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package net.fretux.ascend.network;
|
|||||||
|
|
||||||
import net.fretux.ascend.AscendMod;
|
import net.fretux.ascend.AscendMod;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
|
||||||
import net.minecraftforge.network.NetworkDirection;
|
import net.minecraftforge.network.NetworkDirection;
|
||||||
import net.minecraftforge.network.NetworkRegistry;
|
import net.minecraftforge.network.NetworkRegistry;
|
||||||
import net.minecraftforge.network.simple.SimpleChannel;
|
import net.minecraftforge.network.simple.SimpleChannel;
|
||||||
@@ -13,10 +12,6 @@ public class PacketHandler {
|
|||||||
private static int id = 0;
|
private static int id = 0;
|
||||||
|
|
||||||
public static void register() {
|
public static void register() {
|
||||||
System.out.println("[Ascend] Registering network packets...");
|
|
||||||
System.out.println("[Ascend] Registering packets on side: " +
|
|
||||||
(FMLEnvironment.dist.isClient() ? "CLIENT" : "SERVER"));
|
|
||||||
|
|
||||||
INSTANCE = NetworkRegistry.newSimpleChannel(
|
INSTANCE = NetworkRegistry.newSimpleChannel(
|
||||||
new ResourceLocation(AscendMod.MODID, "main"),
|
new ResourceLocation(AscendMod.MODID, "main"),
|
||||||
() -> PROTOCOL_VERSION,
|
() -> PROTOCOL_VERSION,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package net.fretux.ascend.network;
|
|||||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||||
import net.fretux.ascend.player.StatEffects;
|
import net.fretux.ascend.player.StatEffects;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
import net.minecraftforge.network.PacketDistributor;
|
import net.minecraftforge.network.PacketDistributor;
|
||||||
@@ -40,14 +39,6 @@ public class ServerboundSpendPointPacket {
|
|||||||
PacketDistributor.PLAYER.with(() -> player),
|
PacketDistributor.PLAYER.with(() -> player),
|
||||||
new ClientboundSyncStatsPacket(data)
|
new ClientboundSyncStatsPacket(data)
|
||||||
);
|
);
|
||||||
player.sendSystemMessage(Component.literal("You increased " + attribute + "!"));
|
|
||||||
} else {
|
|
||||||
int level = stats.getAttributeLevel(attribute);
|
|
||||||
int cost = stats.getCostToUpgrade(attribute);
|
|
||||||
int have = stats.getUnspentPoints();
|
|
||||||
player.sendSystemMessage(Component.literal(
|
|
||||||
"Not enough points (" + have + "/" + cost + ") to increase " + attribute + " (lvl " + level + ")."
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public final class StatEffects {
|
|||||||
if (kb != null) {
|
if (kb != null) {
|
||||||
kb.removeModifier(STRENGTH_KNOCKBACK_UUID);
|
kb.removeModifier(STRENGTH_KNOCKBACK_UUID);
|
||||||
if (strengthLevel > 0) {
|
if (strengthLevel > 0) {
|
||||||
double kbBonus = strengthLevel * 0.03d * getScaling();
|
double kbBonus = strengthLevel * 0.015d * getScaling();
|
||||||
kb.addTransientModifier(new AttributeModifier(
|
kb.addTransientModifier(new AttributeModifier(
|
||||||
STRENGTH_KNOCKBACK_UUID,
|
STRENGTH_KNOCKBACK_UUID,
|
||||||
"Ascend Strength knockback bonus",
|
"Ascend Strength knockback bonus",
|
||||||
@@ -78,7 +78,7 @@ public final class StatEffects {
|
|||||||
if (move != null) {
|
if (move != null) {
|
||||||
move.removeModifier(AGILITY_SPEED_UUID);
|
move.removeModifier(AGILITY_SPEED_UUID);
|
||||||
if (agilityLevel > 0) {
|
if (agilityLevel > 0) {
|
||||||
double bonus = agilityLevel * 0.002d * getScaling();
|
double bonus = agilityLevel * 0.0005d * getScaling();
|
||||||
move.addTransientModifier(new AttributeModifier(
|
move.addTransientModifier(new AttributeModifier(
|
||||||
AGILITY_SPEED_UUID,
|
AGILITY_SPEED_UUID,
|
||||||
"Ascend Agility speed bonus",
|
"Ascend Agility speed bonus",
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"key.ascend.open_stats": "Open Ascend Stats",
|
||||||
|
"key.categories.inventory": "Inventory",
|
||||||
|
"ascend.stats.title": "Ascend Stats",
|
||||||
|
"ascend.stats.level": "Level: %s/%s",
|
||||||
|
"ascend.stats.xp": "Ascend XP: %s / %s",
|
||||||
|
"ascend.stats.xp_max": "Ascend XP: MAX",
|
||||||
|
"ascend.stats.unspent": "Unspent Points: %s",
|
||||||
|
|
||||||
|
"ascend.attribute.strength": "Strength",
|
||||||
|
"ascend.attribute.strength.desc": "Increases melee damage, knockback and armor penetration.",
|
||||||
|
"ascend.attribute.agility": "Agility",
|
||||||
|
"ascend.attribute.agility.desc": "Increases movement speed and mobility.",
|
||||||
|
"ascend.attribute.fortitude": "Fortitude",
|
||||||
|
"ascend.attribute.fortitude.desc": "Increases max health and knockback resistance.",
|
||||||
|
"ascend.attribute.intelligence": "Intelligence",
|
||||||
|
"ascend.attribute.intelligence.desc": "Boosts mana, spell power, mana regen & cooldown reduction (with Iron's Spellbooks).",
|
||||||
|
"ascend.attribute.willpower": "Willpower",
|
||||||
|
"ascend.attribute.willpower.desc": "Reduces sanity drain and improves stamina/tempo.",
|
||||||
|
"ascend.attribute.charisma": "Charisma",
|
||||||
|
"ascend.attribute.charisma.desc": "Increases max mana and improves trade deals.",
|
||||||
|
"ascend.attribute.light_scaling": "Light Scaling",
|
||||||
|
"ascend.attribute.light_scaling.desc": "Improves light weapon performance.",
|
||||||
|
"ascend.attribute.medium_scaling": "Medium Scaling",
|
||||||
|
"ascend.attribute.medium_scaling.desc": "Improves medium weapon performance.",
|
||||||
|
"ascend.attribute.heavy_scaling": "Heavy Scaling",
|
||||||
|
"ascend.attribute.heavy_scaling.desc": "Improves heavy weapon performance.",
|
||||||
|
"ascend.attribute.magic_scaling": "Magic Scaling",
|
||||||
|
"ascend.attribute.magic_scaling.desc": "Increases spell power and mana efficiency for scaling spells.",
|
||||||
|
|
||||||
|
"ascend.attribute.display": "%s: %s"
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user