Improve UI and Update README

This commit is contained in:
2025-11-09 00:38:55 +01:00
parent 0a3fec8cdc
commit aad35c586f
3 changed files with 93 additions and 53 deletions
+35
View File
@@ -0,0 +1,35 @@
# Ascend: SbA (Stats by Actions) — short overview
**Ascend** turns vanilla Minecraft into a lightweight, persistent RPG: train attributes by doing things in-game, gain Ascend levels, spend points to boost combat, movement, magic and social skills, and watch those choices change how your character performs.
## What it does (quick)
* Adds an **Ascend level & XP** system (max level **20**, **15 points per level**).
* Players earn XP from actions: killing mobs, mining certain blocks, taking damage, crafting/smelting, using potions, trading with villagers, using weapons, and periodic checks for risky situations (low health, debuffs, darkness).
* Spend earned points on 10+ attributes (strength, agility, fortitude, intelligence, willpower, charisma, and weapon/magic scaling stats).
* Attribute points apply **live** via attribute modifiers and event hooks (damage, health, movement speed, enchant/potion interactions, trade discounts, etc.).
* Client UI: press **V** (configurable keybind) to open a compact stats screen and spend points. Server-authoritative with packet sync.
## Key mechanics & examples
* **Strength**: +attack damage, +knockback, and armor-bypass bonus calculated on hit.
* **Agility**: small movement speed bonus; XP for agile actions (sprinting, climbing, jumping).
* **Fortitude**: increases max health, knockback resistance, chance to resist/cleanse harmful effects.
* **Intelligence**: increases mana (and integrates with Iron’s Spellbooks if present), lengthens beneficial potion effects, reduces enchantment costs/effects.
* **Willpower**: reduces sanity drain and increases tempo/stamina gains (API helpers available).
* **Charisma**: grants trade discounts by adjusting merchant offers when opening trades.
* **Scaling stats**: light/medium/heavy weapon scaling and magic scaling multiply damage based on attack speed or magic damage type.
## Compatibility & tech notes
* Designed for **Forge 1.20.1** (example build uses Forge 47.4.0) and **Java 17** toolchain.
* Optional compat with **Iron’s Spellbooks** (adds mana/spell-power hooks). Also prepared to play nicely with Geckolib, Caelus, Curios, Player Animator (as declared in the build).
* Uses a capability (`PlayerStats`) for persistent storage and network packets to sync server → client. Attributes are capped (per-mod caps and MAX_ATTRIBUTE_POINTS = 100).
## Playstyle & design goal
Ascend is built to be unobtrusive and organic: your playstyle trains the corresponding attributes. Want a heavy-hitter who tanks? Smash armor and spend in Strength/Fortitude. Prefer spellcasting? Farm XP and invest in Intelligence and Magic Scaling. It’s about emergent progression — no grindy menus, just meaningful choices.
---
Short, modular, and ready to extend — Ascend gives you an RPG progression layer without changing world generation or requiring a new economy. Want a longer description, a Steam-like blurb, or a README-ready install/FAQ section? I can write that next.
-46
View File
@@ -1,46 +0,0 @@
Source installation information for modders
-------------------------------------------
This code follows the Minecraft Forge installation methodology. It will apply
some small patches to the vanilla MCP source code, giving you and it access
to some of the data and functions you need to build a successful mod.
Note also that the patches are built against "un-renamed" MCP source code (aka
SRG Names) - this means that you will not be able to read them directly against
normal code.
Setup Process:
==============================
Step 1: Open your command-line and browse to the folder where you extracted the zip file.
Step 2: You're left with a choice.
If you prefer to use Eclipse:
1. Run the following command: `./gradlew genEclipseRuns`
2. Open Eclipse, Import > Existing Gradle Project > Select Folder
or run `gradlew eclipse` to generate the project.
If you prefer to use IntelliJ:
1. Open IDEA, and import project.
2. Select your build.gradle file and have it import.
3. Run the following command: `./gradlew genIntellijRuns`
4. Refresh the Gradle Project in IDEA if required.
If at any point you are missing libraries in your IDE, or you've run into problems you can
run `gradlew --refresh-dependencies` to refresh the local cache. `gradlew clean` to reset everything
(this does not affect your code) and then start the process again.
Mapping Names:
=============================
By default, the MDK is configured to use the official mapping names from Mojang for methods and fields
in the Minecraft codebase. These names are covered by a specific license. All modders should be aware of this
license, if you do not agree with it you can change your mapping names to other crowdsourced names in your
build.gradle. For the latest license text, refer to the mapping file itself, or the reference copy here:
https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md
Additional Resources:
=========================
Community Documentation: https://docs.minecraftforge.net/en/1.20.1/gettingstarted/
LexManos' Install Video: https://youtu.be/8VEdtQLuLO0
Forge Forums: https://forums.minecraftforge.net/
Forge Discord: https://discord.minecraftforge.net/
@@ -31,6 +31,45 @@ public class StatsScreen extends Screen {
private final Map<String, Button> plusButtons = new HashMap<>(); private final Map<String, Button> plusButtons = new HashMap<>();
// --- Tooltips for attributes ---
private static final Map<String, Component> ATTRIBUTE_TOOLTIPS = new HashMap<>();
static {
ATTRIBUTE_TOOLTIPS.put("strength", Component.literal(
"Strength: Increases melee damage, knockback and armor penetration."
));
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() { public StatsScreen() {
super(Component.literal("Ascend Stats")); super(Component.literal("Ascend Stats"));
} }
@@ -40,8 +79,10 @@ public class StatsScreen extends Screen {
super.init(); super.init();
this.leftPos = (this.width - WIDTH) / 2; this.leftPos = (this.width - WIDTH) / 2;
this.topPos = (this.height - HEIGHT) / 2; this.topPos = (this.height - HEIGHT) / 2;
this.plusButtons.clear(); this.plusButtons.clear();
this.clearWidgets(); this.clearWidgets();
int y = topPos + 55; int y = topPos + 55;
for (String attr : ATTRIBUTES) { for (String attr : ATTRIBUTES) {
final String key = attr; final String key = attr;
@@ -54,6 +95,7 @@ public class StatsScreen extends Screen {
this.plusButtons.put(key, plus); this.plusButtons.put(key, plus);
y += 16; y += 16;
} }
Button done = Button.builder(Component.translatable("gui.done"), (btn) -> onClose()) Button done = Button.builder(Component.translatable("gui.done"), (btn) -> onClose())
.bounds(leftPos + WIDTH / 2 - 40, topPos + HEIGHT - 24, 80, 20) .bounds(leftPos + WIDTH / 2 - 40, topPos + HEIGHT - 24, 80, 20)
.build(); .build();
@@ -67,6 +109,7 @@ public class StatsScreen extends Screen {
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, this.title, this.width / 2, topPos + 8, 0xFFFFFF);
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 -> {
int level = stats.getAscendLevel(); int level = stats.getAscendLevel();
@@ -88,13 +131,11 @@ public class StatsScreen extends Screen {
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 sourceXP = stats.getAscendXP();
int cost = stats.getCostToUpgrade(key); int cost = stats.getCostToUpgrade(key);
String niceName = formatAttributeName(key); String niceName = formatAttributeName(key);
gui.drawString(font, String label = niceName + ": " + attrLevel;
niceName + ": " + attrLevel, int labelX = leftPos + 10;
leftPos + 10, y, gui.drawString(font, label, labelX, y, 0xFFFFFF);
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);
@@ -102,13 +143,23 @@ 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 labelHeight = font.lineHeight;
if (mouseX >= labelX && mouseX <= labelX + labelWidth
&& mouseY >= y && mouseY <= y + labelHeight) {
hoveredAttributeKey = key;
}
y += 16; y += 16;
} }
}); });
} }
super.render(gui, mouseX, mouseY, partialTicks); super.render(gui, mouseX, mouseY, partialTicks);
if (hoveredAttributeKey != null) {
Component tooltip = ATTRIBUTE_TOOLTIPS.get(hoveredAttributeKey);
if (tooltip != null) {
gui.renderTooltip(this.font, tooltip, mouseX, mouseY);
}
}
} }
private String formatAttributeName(String key) { private String formatAttributeName(String key) {