From aad35c586fb8bb3183045545b61a8207898c537d Mon Sep 17 00:00:00 2001 From: fretuks Date: Sun, 9 Nov 2025 00:38:55 +0100 Subject: [PATCH] Improve UI and Update README --- README.md | 35 ++++++++++ README.txt | 46 ------------- .../ascend/client/screen/StatsScreen.java | 65 +++++++++++++++++-- 3 files changed, 93 insertions(+), 53 deletions(-) create mode 100644 README.md delete mode 100644 README.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000..541e4c9 --- /dev/null +++ b/README.md @@ -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. \ No newline at end of file diff --git a/README.txt b/README.txt deleted file mode 100644 index 46add15..0000000 --- a/README.txt +++ /dev/null @@ -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/ diff --git a/src/main/java/net/fretux/ascend/client/screen/StatsScreen.java b/src/main/java/net/fretux/ascend/client/screen/StatsScreen.java index cb4df3b..807dafd 100644 --- a/src/main/java/net/fretux/ascend/client/screen/StatsScreen.java +++ b/src/main/java/net/fretux/ascend/client/screen/StatsScreen.java @@ -31,6 +31,45 @@ public class StatsScreen extends Screen { private final Map plusButtons = new HashMap<>(); + // --- Tooltips for attributes --- + private static final Map 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() { super(Component.literal("Ascend Stats")); } @@ -40,8 +79,10 @@ public class StatsScreen extends Screen { super.init(); this.leftPos = (this.width - WIDTH) / 2; this.topPos = (this.height - HEIGHT) / 2; + this.plusButtons.clear(); this.clearWidgets(); + int y = topPos + 55; for (String attr : ATTRIBUTES) { final String key = attr; @@ -54,6 +95,7 @@ public class StatsScreen extends Screen { this.plusButtons.put(key, plus); y += 16; } + Button done = Button.builder(Component.translatable("gui.done"), (btn) -> onClose()) .bounds(leftPos + WIDTH / 2 - 40, topPos + HEIGHT - 24, 80, 20) .build(); @@ -67,6 +109,7 @@ public class StatsScreen extends Screen { gui.fill(leftPos - 4, topPos - 4, leftPos + WIDTH + 4, topPos + HEIGHT + 4, 0xAA000000); RenderSystem.disableBlend(); gui.drawCenteredString(this.font, this.title, this.width / 2, topPos + 8, 0xFFFFFF); + hoveredAttributeKey = null; if (mc.player != null) { mc.player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> { int level = stats.getAscendLevel(); @@ -88,13 +131,11 @@ public class StatsScreen extends Screen { int y = topPos + 55; for (String key : ATTRIBUTES) { int attrLevel = stats.getAttributeLevel(key); - int sourceXP = stats.getAscendXP(); int cost = stats.getCostToUpgrade(key); String niceName = formatAttributeName(key); - gui.drawString(font, - niceName + ": " + attrLevel, - leftPos + 10, y, - 0xFFFFFF); + String label = niceName + ": " + attrLevel; + int labelX = leftPos + 10; + gui.drawString(font, label, labelX, y, 0xFFFFFF); Button plus = plusButtons.get(key); if (plus != null) { plus.setX(leftPos + WIDTH - 40); @@ -102,13 +143,23 @@ public class StatsScreen extends Screen { plus.active = (unspent >= 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; } }); } - 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) {