Skip to content

Commit d4662ec

Browse files
added 3-mode toggles for hide features, default to all affixes shown, fixed alt prompt rendering
1 parent d18c6a3 commit d4662ec

12 files changed

Lines changed: 224 additions & 121 deletions

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ A Forge 1.20.1 mod that cleans up the affix and gem tooltips Apotheosis adds to
1010
- Merge empty sockets on socketed items into one summary line. Mixed sockets are supported: filled gems still render, with the empty count shown below.
1111
- Hide the bonus durability line.
1212
- Hide the Apotheosis affix summary block (Cold/Fire/HP%/Spell Resistance lines).
13-
- Hide the affix source line.
13+
- Always hide the affix source line (not configurable).
1414
- Hide the `[⌛ MM:SS]` cooldown markers and `[Stacking]` tags on affix lines without touching the affix text. Hold Alt to reveal.
1515
- Custom rarity color overrides for all six tiers (Common, Uncommon, Rare, Epic, Mythic, Ancient). Esoteric (Apotheotic Additions) maps to Ancient via namespace fallback.
1616
- Strip prefixes from affix names.
@@ -22,33 +22,35 @@ A Forge 1.20.1 mod that cleans up the affix and gem tooltips Apotheosis adds to
2222

2323
Settings live in `config/apothic_tooltip_cleanup-client.toml`. The file regenerates from defaults if deleted.
2424

25+
Most hide features use a three-mode toggle: `show` keeps the content fully visible, `alt` hides it by default and reveals it while Alt is held, and `delete` hides it permanently with no Alt reveal.
26+
2527
## config reference
2628

2729
### affix display
2830

2931
`affix_display_mode` controls how affixes show on tooltips. Three options: `all` shows every affix, `top_n` shows the first N with Alt to expand the rest (default), `alt_only` hides every affix unless Alt is held.
3032

31-
The "Hold Alt for full details" prompt also appears when other handlers hide content. With `hide_durability_bonus` enabled, the prompt shows on durable items even when no affixes were truncated; pressing Alt reveals the durability line.
33+
The "Hold Alt for full details" prompt also appears when other handlers hide content. With `durability_bonus_mode` set to `alt` (the default), the prompt shows on durable items even when no affixes were truncated; pressing Alt reveals the durability line.
3234

3335
`affix_visible_count` is the N for `top_n` mode. Default 3.
3436

3537
`affix_sort_order` is one of `default`, `rarity`, `alphabetical`, `type`.
3638

37-
`clean_affix_prefixes` strips prefixes from affix names. Off by default.
39+
`affix_prefixes_mode` controls the affix type prefixes (While held, On hit, On block, Passive). `show` (default) keeps them, `alt` hides them unless Alt is held, `delete` removes them permanently.
3840

3941
`hidden_affix_ids` is a list of translation key prefixes for affixes you want hidden entirely.
4042

4143
### affix tooltip lines
4244

43-
`hide_source_line` hides the affix source line.
45+
The affix source line is always hidden. There is no config option for it.
4446

45-
`disable_summarization` hides the Apotheosis summary block (Cold/Fire/HP%/Spell Resistance).
47+
`summarization_mode` controls the Apotheosis summary block (Cold/Fire/HP%/Spell Resistance). `show` keeps it, `alt` (default) hides it unless Alt is held, `delete` removes it permanently.
4648

47-
`hide_durability_bonus` hides the "ignores X% of durability damage" line.
49+
`durability_bonus_mode` controls the "ignores X% of durability damage" line. `show` keeps it, `alt` (default) hides it unless Alt is held, `delete` removes it permanently.
4850

49-
`disable_potion_descriptions` hides potion-style affix descriptions.
51+
`potion_descriptions_mode` controls potion-style affix descriptions. `show` (default) keeps them, `alt` hides them unless Alt is held, `delete` removes them permanently.
5052

51-
`hide_affix_extras` hides the `[⌛ MM:SS]` cooldown markers and `[Stacking]` modifier tags on affix lines. The affix text itself stays intact; only the bracketed annotations are stripped. Holding Alt while the item is hovered reveals the full line including the hidden markers.
53+
`affix_extras_mode` controls the `[⌛ MM:SS]` cooldown markers and `[Stacking]` tags on affix lines; the affix text itself is never touched, only the bracketed annotations. `show` keeps them, `alt` (default) hides them unless Alt is held, `delete` removes them permanently.
5254

5355
### gem display
5456

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ mod_name=Apothic Tooltip Cleanup
4848
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
4949
mod_license=MIT
5050
# The mod version. See https://semver.org/
51-
mod_version=1.1.1
51+
mod_version=1.2.0
5252
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
5353
# This should match the base package used for the mod sources.
5454
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
5555
mod_group_id=com.nightwielder.apothictooltipcleanup
5656
# The authors of the mod. This is a simple text string that is used for display purposes in the mod list.
5757
mod_authors=Nightwielder23
5858
# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list.
59-
mod_description=Cleans up Apotheosis affix and gem tooltips. Configurable per feature. Client side, soft dependency on Apotheosis.
59+
mod_description=Cleans up Apotheosis affix and gem tooltips. Hideable features each toggle show, alt, or delete. Client side, soft dependency on Apotheosis.

src/main/java/com/nightwielder/apothictooltipcleanup/Config.java

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.nightwielder.apothictooltipcleanup;
22

3+
import com.nightwielder.apothictooltipcleanup.util.HideMode;
34
import net.minecraftforge.common.ForgeConfigSpec;
45

56
import java.util.Arrays;
@@ -14,15 +15,14 @@ public class Config {
1415
public static final ForgeConfigSpec.IntValue AFFIX_VISIBLE_COUNT;
1516
public static final ForgeConfigSpec.BooleanValue SHIFT_TO_EXPAND;
1617
public static final ForgeConfigSpec.ConfigValue<String> AFFIX_SORT_ORDER;
17-
public static final ForgeConfigSpec.BooleanValue CLEAN_AFFIX_PREFIXES;
18+
public static final ForgeConfigSpec.ConfigValue<String> AFFIX_PREFIXES_MODE;
1819
public static final ForgeConfigSpec.ConfigValue<List<? extends String>> HIDDEN_AFFIX_IDS;
1920

2021
// Affix tooltip lines
21-
public static final ForgeConfigSpec.BooleanValue HIDE_SOURCE_LINE;
22-
public static final ForgeConfigSpec.BooleanValue DISABLE_SUMMARIZATION;
23-
public static final ForgeConfigSpec.BooleanValue HIDE_DURABILITY_BONUS;
24-
public static final ForgeConfigSpec.BooleanValue DISABLE_POTION_DESCRIPTIONS;
25-
public static final ForgeConfigSpec.BooleanValue HIDE_AFFIX_EXTRAS;
22+
public static final ForgeConfigSpec.ConfigValue<String> SUMMARIZATION_MODE;
23+
public static final ForgeConfigSpec.ConfigValue<String> DURABILITY_BONUS_MODE;
24+
public static final ForgeConfigSpec.ConfigValue<String> POTION_DESCRIPTIONS_MODE;
25+
public static final ForgeConfigSpec.ConfigValue<String> AFFIX_EXTRAS_MODE;
2626

2727
// Gem display (raw gems)
2828
public static final ForgeConfigSpec.ConfigValue<String> GEM_TOOLTIP_MODE;
@@ -52,16 +52,19 @@ public class Config {
5252
" all = show every affix",
5353
" top_n = show first N, rest visible with Alt held",
5454
" alt_only = hide every affix unless Alt is held");
55-
AFFIX_DISPLAY_MODE = builder.defineInList("affix_display_mode", "top_n", Arrays.asList("all", "top_n", "alt_only"));
55+
AFFIX_DISPLAY_MODE = builder.defineInList("affix_display_mode", "all", Arrays.asList("all", "top_n", "alt_only"));
5656

5757
builder.comment(" Number of affixes shown when mode is top_n.");
5858
AFFIX_VISIBLE_COUNT = builder.defineInRange("affix_visible_count", 3, 0, 99);
5959

6060
builder.comment(" Sort order: default, rarity, alphabetical, type.");
6161
AFFIX_SORT_ORDER = builder.defineInList("affix_sort_order", "default", Arrays.asList("default", "rarity", "alphabetical", "type"));
6262

63-
builder.comment(" Strips prefixes from affix names.");
64-
CLEAN_AFFIX_PREFIXES = builder.define("clean_affix_prefixes", false);
63+
builder.comment(" Affix type prefixes (While held, On hit, On block, Passive).",
64+
" show = always visible",
65+
" alt = hidden unless Alt is held",
66+
" delete = always hidden, Alt has no effect");
67+
AFFIX_PREFIXES_MODE = builder.defineInList("affix_prefixes_mode", HideMode.SHOW, HideMode.OPTIONS);
6568

6669
builder.comment(" Translation key prefixes of affixes to hide.");
6770
HIDDEN_AFFIX_IDS = builder.defineListAllowEmpty("hidden_affix_ids", Collections.emptyList(), o -> o instanceof String);
@@ -71,22 +74,30 @@ public class Config {
7174

7275
builder.comment(" affix tooltip lines",
7376
" ============================================================",
74-
" Hides the affix source line.");
75-
HIDE_SOURCE_LINE = builder.define("hide_source_line", false);
76-
77-
builder.comment(" Hides the summary block (Cold/Fire/HP%/Spell Resistance lines).");
78-
DISABLE_SUMMARIZATION = builder.define("disable_summarization", false);
79-
80-
builder.comment(" Hides the \"ignores X% of durability damage\" line.");
81-
HIDE_DURABILITY_BONUS = builder.define("hide_durability_bonus", false);
82-
83-
builder.comment(" Hides potion-style affix descriptions.");
84-
DISABLE_POTION_DESCRIPTIONS = builder.define("disable_potion_descriptions", false);
85-
86-
builder.comment(" Hides the [⌛ MM:SS] cooldown markers and [Stacking] tags on affix lines.",
87-
" Strips just the annotations, the affix text remains unchanged.",
88-
" Hold Alt to view the full line including markers.");
89-
HIDE_AFFIX_EXTRAS = builder.define("hide_affix_extras", true);
77+
" The summary block (Cold/Fire/HP%/Spell Resistance lines).",
78+
" show = always visible",
79+
" alt = hidden unless Alt is held",
80+
" delete = always hidden, Alt has no effect");
81+
SUMMARIZATION_MODE = builder.defineInList("summarization_mode", HideMode.ALT, HideMode.OPTIONS);
82+
83+
builder.comment(" The \"ignores X% of durability damage\" line.",
84+
" show = always visible",
85+
" alt = hidden unless Alt is held",
86+
" delete = always hidden, Alt has no effect");
87+
DURABILITY_BONUS_MODE = builder.defineInList("durability_bonus_mode", HideMode.ALT, HideMode.OPTIONS);
88+
89+
builder.comment(" Potion-style affix descriptions.",
90+
" show = always visible",
91+
" alt = hidden unless Alt is held",
92+
" delete = always hidden, Alt has no effect");
93+
POTION_DESCRIPTIONS_MODE = builder.defineInList("potion_descriptions_mode", HideMode.SHOW, HideMode.OPTIONS);
94+
95+
builder.comment(" The [⌛ MM:SS] cooldown markers and [Stacking] tags on affix lines.",
96+
" The affix text itself is never touched, only the annotations.",
97+
" show = always visible",
98+
" alt = hidden unless Alt is held",
99+
" delete = always hidden, Alt has no effect");
100+
AFFIX_EXTRAS_MODE = builder.defineInList("affix_extras_mode", HideMode.ALT, HideMode.OPTIONS);
90101

91102
builder.comment(" gem display (raw gems)",
92103
" ============================================================",

src/main/java/com/nightwielder/apothictooltipcleanup/handler/AffixMarkerStripper.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.nightwielder.apothictooltipcleanup.handler;
22

33
import com.nightwielder.apothictooltipcleanup.Config;
4+
import com.nightwielder.apothictooltipcleanup.util.HideMode;
45
import com.nightwielder.apothictooltipcleanup.util.TooltipMatcher;
56
import net.minecraft.client.gui.screens.Screen;
67
import net.minecraft.network.chat.Component;
@@ -23,33 +24,41 @@ public final class AffixMarkerStripper {
2324

2425
private AffixMarkerStripper() {}
2526

26-
public static void apply(List<Component> tooltip) {
27-
if (!Config.HIDE_AFFIX_EXTRAS.get()) return;
28-
// Holding Alt reveals the unstripped line, matching AltExpandHandler's reveal-on-hold UX.
29-
if (Screen.hasAltDown()) return;
27+
// Returns true only when a marker was stripped in Alt-revealable form (alt mode, Alt up), so
28+
// AltExpandHandler shows the reveal prompt. show and delete modes never set that signal.
29+
public static boolean apply(List<Component> tooltip) {
30+
String mode = Config.AFFIX_EXTRAS_MODE.get();
31+
boolean altDown = Screen.hasAltDown();
32+
if (!HideMode.hides(mode, altDown)) return false;
33+
boolean stripped = false;
3034
for (Component line : tooltip) {
3135
if (!TooltipMatcher.isBulletPrefix(line)) continue;
3236
String text = line.getString();
3337
if (text.indexOf('⌛') < 0 && !text.contains("[Stacking]")) continue;
3438
if (!(line.getContents() instanceof TranslatableContents tc)) continue;
3539
Object[] args = tc.getArgs();
3640
if (args.length == 0 || !(args[0] instanceof Component inner)) continue;
37-
stripMarkerSiblings(inner.getSiblings());
41+
stripped |= stripMarkerSiblings(inner.getSiblings());
3842
}
43+
return stripped && HideMode.revealable(mode, altDown);
3944
}
4045

4146
// Reverse walk so removals don't invalidate later indices. When a marker sibling is removed
4247
// we also drop the preceding " " separator so the bullet doesn't render with a trailing space.
43-
private static void stripMarkerSiblings(List<Component> siblings) {
48+
// Returns true if any marker sibling was removed.
49+
private static boolean stripMarkerSiblings(List<Component> siblings) {
50+
boolean removed = false;
4451
for (int i = siblings.size() - 1; i >= 0; i--) {
4552
String key = TooltipMatcher.getKey(siblings.get(i));
4653
if (!COOLDOWN_KEY.equals(key) && !STACKING_KEY.equals(key)) continue;
4754
siblings.remove(i);
55+
removed = true;
4856
if (i > 0 && isLiteralSpace(siblings.get(i - 1))) {
4957
siblings.remove(i - 1);
5058
i--;
5159
}
5260
}
61+
return removed;
5362
}
5463

5564
private static boolean isLiteralSpace(Component component) {

src/main/java/com/nightwielder/apothictooltipcleanup/handler/AltExpandHandler.java

Lines changed: 71 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,61 +15,94 @@ private AltExpandHandler() {}
1515
// shift_to_expand is fully deprecated and no longer read; affix_display_mode controls this now.
1616
// Shift triggers vanilla quick-move and EpicFight's innate skill display, and Ctrl conflicts
1717
// with other tooltip mods, so the expand gate is Alt.
18-
public static void apply(List<Component> tooltip) {
19-
String mode = Config.AFFIX_DISPLAY_MODE.get();
20-
if ("all".equalsIgnoreCase(mode)) return;
18+
//
19+
// Runs last in the tooltip pass: it truncates affixes for top_n / alt_only mode and adds the
20+
// single "Hold Alt for full details" prompt. anyAltRevealableHidden carries whether any feature
21+
// hid content this pass that Alt can bring back; delete-mode hides are excluded, so the prompt
22+
// never promises to reveal something it cannot. The prompt shows for those reveals even when
23+
// affix truncation is off (mode = all).
24+
public static void apply(List<Component> tooltip, boolean anyAltRevealableHidden) {
25+
// Alt held: every hide handler no-ops this pass, so the user already sees everything and no
26+
// prompt is needed.
2127
if (Screen.hasAltDown()) return;
2228

23-
// Apoth 7.x renders "Fits in:" as a literal Component without a translation key, so we
24-
// detect gem tooltips by exact text match instead. gem Fits In bullets use the same
25-
// dot_prefix key as affix bullets, so without this bail the truncation budget would eat
26-
// gem categories on multi-category gems.
27-
for (Component line : tooltip) {
28-
if ("Fits in:".equals(line.getString())) {
29-
return;
30-
}
31-
}
29+
boolean anythingHidden = anyAltRevealableHidden;
30+
int insertIndex = -1;
3231

33-
boolean altOnly = "alt_only".equalsIgnoreCase(mode);
34-
int visibleCount = altOnly ? 0 : Math.max(0, Config.AFFIX_VISIBLE_COUNT.get());
32+
// Truncation only applies outside "all" mode, and never on gem tooltips: gem "Fits in:"
33+
// bullets share the dot_prefix key with affix lines, so the budget would otherwise eat
34+
// gem categories on multi-category gems.
35+
String mode = Config.AFFIX_DISPLAY_MODE.get();
36+
if (!"all".equalsIgnoreCase(mode) && !isGemTooltip(tooltip)) {
37+
boolean altOnly = "alt_only".equalsIgnoreCase(mode);
38+
int visibleCount = altOnly ? 0 : Math.max(0, Config.AFFIX_VISIBLE_COUNT.get());
3539

36-
int affixesKept = 0;
37-
int liveIndex = 0;
38-
int insertIndex = -1;
39-
// True if this handler removed any line. The prompt must appear whenever Alt would reveal
40-
// something, including the case where only the durability bonus was stripped and no
41-
// affixes were truncated.
42-
boolean anythingHidden = false;
43-
Iterator<Component> it = tooltip.iterator();
44-
while (it.hasNext()) {
45-
Component line = it.next();
46-
if (DurabilityHider.isDurableLine(line)) {
47-
if (insertIndex < 0) insertIndex = liveIndex;
48-
it.remove();
49-
anythingHidden = true;
50-
continue;
51-
}
52-
if (TooltipMatcher.isAffixLine(line)) {
53-
if (affixesKept < visibleCount) {
54-
affixesKept++;
40+
int affixesKept = 0;
41+
int liveIndex = 0;
42+
Iterator<Component> it = tooltip.iterator();
43+
while (it.hasNext()) {
44+
Component line = it.next();
45+
// Durability is owned by DurabilityHider; leave it in place rather than counting it
46+
// against the affix budget or truncating it as an affix.
47+
if (DurabilityHider.isDurableLine(line)) {
5548
liveIndex++;
49+
continue;
50+
}
51+
if (TooltipMatcher.isAffixLine(line)) {
52+
if (affixesKept < visibleCount) {
53+
affixesKept++;
54+
liveIndex++;
55+
} else {
56+
if (insertIndex < 0) insertIndex = liveIndex;
57+
it.remove();
58+
anythingHidden = true;
59+
}
5660
} else {
57-
if (insertIndex < 0) insertIndex = liveIndex;
58-
it.remove();
59-
anythingHidden = true;
61+
liveIndex++;
6062
}
61-
} else {
62-
liveIndex++;
6363
}
6464
}
6565

6666
if (!anythingHidden) return;
6767

68+
// With no truncation (mode = all) nothing set insertIndex. Appending at the end drops the
69+
// prompt below the attribute block, where a tall tooltip clips it off the bottom of the
70+
// screen, so anchor it right after the last affix line instead.
71+
if (insertIndex < 0) {
72+
insertIndex = lastAffixInsertIndex(tooltip);
73+
}
74+
6875
Component prompt = Component.literal("Hold Alt for full details").withStyle(ChatFormatting.DARK_GRAY);
6976
if (insertIndex >= 0 && insertIndex <= tooltip.size()) {
7077
tooltip.add(insertIndex, prompt);
7178
} else {
7279
tooltip.add(prompt);
7380
}
7481
}
82+
83+
// Index just after the last affix line. Falls back to the start of the vanilla attribute block
84+
// ("When in Main Hand:" et al, keyed item.modifiers.*), then to -1 so the caller appends.
85+
private static int lastAffixInsertIndex(List<Component> tooltip) {
86+
int lastAffix = -1;
87+
int attributeBlock = -1;
88+
for (int i = 0; i < tooltip.size(); i++) {
89+
Component line = tooltip.get(i);
90+
if (TooltipMatcher.isAffixLine(line)) {
91+
lastAffix = i;
92+
} else if (attributeBlock < 0 && TooltipMatcher.keyStartsWith(line, "item.modifiers.")) {
93+
attributeBlock = i;
94+
}
95+
}
96+
if (lastAffix >= 0) return lastAffix + 1;
97+
return attributeBlock;
98+
}
99+
100+
// Apoth 7.x renders "Fits in:" as a literal Component without a translation key, so gem
101+
// tooltips are detected by exact text match.
102+
private static boolean isGemTooltip(List<Component> tooltip) {
103+
for (Component line : tooltip) {
104+
if ("Fits in:".equals(line.getString())) return true;
105+
}
106+
return false;
107+
}
75108
}

0 commit comments

Comments
 (0)