Skip to content

Commit c3ed5de

Browse files
fixed prefix deletion, unified gem category filtering, and removed mojibake
1 parent 36d6e4b commit c3ed5de

6 files changed

Lines changed: 143 additions & 71 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ The "Hold Alt for full details" prompt also appears when other handlers hide con
3535

3636
`affix_sort_order` is one of `default`, `rarity`, `alphabetical`, `type`.
3737

38-
`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.
38+
`affix_prefixes_mode` controls the affix prefix and suffix Apotheosis adds to the item name, like "Strengthened" or "of the Inferno". `show` (default) keeps the full name, `alt` shows the base item name unless Alt is held, `delete` always shows the base item name.
3939

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

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ public class Config {
5151
builder.comment(" Sort order: default, rarity, alphabetical, type.");
5252
AFFIX_SORT_ORDER = builder.defineInList("affix_sort_order", "default", Arrays.asList("default", "rarity", "alphabetical", "type"));
5353

54-
builder.comment(" Affix type prefixes (While held, On hit, On block, Passive).",
55-
" show = always visible",
56-
" alt = hidden unless Alt is held",
57-
" delete = always hidden, Alt has no effect");
54+
builder.comment(" The affix prefix and suffix Apotheosis adds to the item name (Strengthened, of the Inferno).",
55+
" show = full affixed name",
56+
" alt = base item name unless Alt is held",
57+
" delete = always the base item name");
5858
AFFIX_PREFIXES_MODE = builder.defineInList("affix_prefixes_mode", HideMode.SHOW, HideMode.OPTIONS);
5959

6060
builder.comment(" Translation key prefixes of affixes to hide.");
@@ -80,7 +80,7 @@ public class Config {
8080
" delete = always hidden, Alt has no effect");
8181
POTION_DESCRIPTIONS_MODE = builder.defineInList("potion_descriptions_mode", HideMode.SHOW, HideMode.OPTIONS);
8282

83-
builder.comment(" The [MM:SS] cooldown markers and [Stacking] tags on affix lines.",
83+
builder.comment(" The [MM:SS] cooldown markers and [Stacking] tags on affix lines.",
8484
" Only the annotations are touched, never the affix text.",
8585
" show = always visible",
8686
" alt = hidden unless Alt is held",

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
// Strips the cooldown marker and [Stacking] tag off affix bullets. Apoth attaches them as siblings
1414
// of the bullet inner component where a string regex never sees them, so the siblings are matched by
15-
// translation key after a quick English only check for the marker glyphs.
15+
// translation key.
1616
public final class AffixMarkerStripper {
1717
private static final String COOLDOWN_KEY = "affix.apotheosis.cooldown";
1818
private static final String STACKING_KEY = "affix.apotheosis.stacking";
@@ -32,10 +32,6 @@ public static boolean apply(List<Component> tooltip) {
3232
if (!TooltipMatcher.isBulletPrefix(line)) {
3333
continue;
3434
}
35-
String text = line.getString();
36-
if (text.indexOf('⌛') < 0 && !text.contains("[Stacking]")) {
37-
continue;
38-
}
3935
if (!(line.getContents() instanceof TranslatableContents tc)) {
4036
continue;
4137
}

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

Lines changed: 119 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ public final class FitsInRemover {
2121
// teal blue Apotheosis uses for the Fits In header and category bullets
2222
private static final int FITS_IN_COLOR = 720650;
2323

24+
// A category in a Fits In bullet: its rendered name, its Apoth id from the translation key (null
25+
// when the key shape is unexpected), and the original component so a filtered bullet stays translatable.
26+
private record Category(String name, String id, Component component) {}
27+
2428
// Output order for ultra mode's category line: weapons, armor, mining tools, then Other. Within a
2529
// group, input order is kept.
2630
private static final LinkedHashMap<String, Set<String>> CATEGORY_GROUPS = new LinkedHashMap<>();
@@ -82,7 +86,7 @@ public static void apply(List<Component> tooltip) {
8286

8387
if (isFits) {
8488
if (ultra) {
85-
List<String> names = sortByGroup(filterHidden(extractCategoryNames(tooltip, i + 1, afterBullets)));
89+
List<String> names = sortByGroup(namesOf(filterHidden(extractCategoriesRange(tooltip, i + 1, afterBullets))));
8690
removeRange(tooltip, i, afterBullets);
8791
if (!names.isEmpty()) {
8892
tooltip.add(i, joinedCategoryBullet(String.join(", ", names)));
@@ -96,20 +100,19 @@ public static void apply(List<Component> tooltip) {
96100
i++;
97101
int bulletIndex = i;
98102
while (bulletIndex < afterBullets && TooltipMatcher.isBulletPrefix(tooltip.get(bulletIndex))) {
99-
String inner = extractBulletText(tooltip.get(bulletIndex));
100-
if (inner == null || inner.isEmpty()) {
103+
List<Category> cats = extractCategories(tooltip.get(bulletIndex));
104+
if (cats.isEmpty()) {
101105
bulletIndex++;
102106
continue;
103107
}
104-
List<String> names = splitCategories(inner);
105-
List<String> kept = filterHidden(names);
106-
if (kept.size() == names.size()) {
108+
List<Category> kept = filterHidden(cats);
109+
if (kept.size() == cats.size()) {
107110
bulletIndex++;
108111
} else if (kept.isEmpty()) {
109112
tooltip.remove(bulletIndex);
110113
afterBullets--;
111114
} else {
112-
tooltip.set(bulletIndex, categoryBullet(String.join(", ", kept)));
115+
tooltip.set(bulletIndex, rebuildCategoryBullet(kept));
113116
bulletIndex++;
114117
}
115118
}
@@ -163,8 +166,7 @@ public static void apply(List<Component> tooltip) {
163166
// full mode keeps Apoth's layout, so walk each Fits In block and drop hidden categories. A bullet
164167
// with nothing left is removed, and so is a header with no bullets under it.
165168
private static void filterFullCategories(List<Component> tooltip) {
166-
List<? extends String> hiddenCategories = Config.HIDDEN_GEM_CATEGORIES.get();
167-
if (hiddenCategories == null || hiddenCategories.isEmpty()) {
169+
if (hiddenSet().isEmpty()) {
168170
return;
169171
}
170172

@@ -186,20 +188,19 @@ private static void filterFullCategories(List<Component> tooltip) {
186188
}
187189

188190
while (bulletIndex < afterBullets) {
189-
String inner = extractBulletText(tooltip.get(bulletIndex));
190-
if (inner == null || inner.isEmpty()) {
191+
List<Category> cats = extractCategories(tooltip.get(bulletIndex));
192+
if (cats.isEmpty()) {
191193
bulletIndex++;
192194
continue;
193195
}
194-
List<String> names = splitCategories(inner);
195-
List<String> kept = filterHidden(names);
196-
if (kept.size() == names.size()) {
196+
List<Category> kept = filterHidden(cats);
197+
if (kept.size() == cats.size()) {
197198
bulletIndex++;
198199
} else if (kept.isEmpty()) {
199200
tooltip.remove(bulletIndex);
200201
afterBullets--;
201202
} else {
202-
tooltip.set(bulletIndex, categoryBullet(String.join(", ", kept)));
203+
tooltip.set(bulletIndex, rebuildCategoryBullet(kept));
203204
bulletIndex++;
204205
}
205206
}
@@ -233,8 +234,7 @@ private static void filterSocketInByCategory(List<Component> tooltip) {
233234
int bulletIndex = i + 1;
234235
int kept = 0;
235236
while (bulletIndex < tooltip.size() && TooltipMatcher.isBulletPrefix(tooltip.get(bulletIndex))) {
236-
String id = socketBonusCategoryId(tooltip.get(bulletIndex));
237-
if (id != null && hidden.contains(id)) {
237+
if (socketBonusHidden(tooltip.get(bulletIndex), hidden)) {
238238
tooltip.remove(bulletIndex);
239239
} else {
240240
kept++;
@@ -251,35 +251,35 @@ private static void filterSocketInByCategory(List<Component> tooltip) {
251251
}
252252
}
253253

254-
// Returns the gem_class id from a Pattern B socket bonus bullet (dot_prefix to "%s: %s" to arg[0]
255-
// keyed gem_class.<id>), or null if the bullet is not that shape.
256-
private static String socketBonusCategoryId(Component bullet) {
254+
// Returns true when a Pattern B socket bonus bullet (dot_prefix to "%s: %s" to arg[0] keyed
255+
// gem_class.<id>) belongs to a hidden category, matching either the gem_class id or its rendered name.
256+
private static boolean socketBonusHidden(Component bullet, Set<String> hidden) {
257257
TranslatableContents outer = TooltipMatcher.translatable(bullet);
258258
if (outer == null || outer.getArgs().length == 0) {
259-
return null;
259+
return false;
260260
}
261261
if (!(outer.getArgs()[0] instanceof Component join)) {
262-
return null;
262+
return false;
263263
}
264264

265265
TranslatableContents joinTc = TooltipMatcher.translatable(join);
266266
if (joinTc == null || joinTc.getArgs().length == 0) {
267-
return null;
267+
return false;
268268
}
269269
if (!(joinTc.getArgs()[0] instanceof Component gemClass)) {
270-
return null;
270+
return false;
271271
}
272272

273273
TranslatableContents gcTc = TooltipMatcher.translatable(gemClass);
274274
if (gcTc == null) {
275-
return null;
275+
return false;
276276
}
277277
String key = gcTc.getKey();
278278
int at = key.lastIndexOf("gem_class.");
279-
if (at < 0) {
280-
return null;
279+
if (at >= 0 && hidden.contains(key.substring(at + "gem_class.".length()))) {
280+
return true;
281281
}
282-
return key.substring(at + "gem_class.".length());
282+
return hidden.contains(gemClass.getString());
283283
}
284284

285285
// Returns the hidden_gem_categories config as a case insensitive set, empty if unset.
@@ -350,16 +350,65 @@ private static List<String> sortByGroup(List<String> categories) {
350350
return sorted;
351351
}
352352

353-
private static List<String> extractCategoryNames(List<Component> tooltip, int from, int toExclusive) {
354-
List<String> names = new ArrayList<>();
355-
for (int k = from; k < toExclusive; k++) {
356-
String inner = extractBulletText(tooltip.get(k));
357-
if (inner == null || inner.isEmpty()) {
358-
continue;
353+
// Pulls each category out of a Fits In dot_prefix bullet as a name and Apoth id. Apoth holds the
354+
// categories as the args of an inner translatable, one component per category keyed
355+
// text.apotheosis.category.<id>.plural, falling back to splitting the rendered text when the shape
356+
// is unexpected such as the "Anything" line or a plain literal.
357+
private static List<Category> extractCategories(Component bullet) {
358+
TranslatableContents outer = TooltipMatcher.translatable(bullet);
359+
if (outer == null || outer.getArgs().length == 0) {
360+
return Collections.emptyList();
361+
}
362+
if (!(outer.getArgs()[0] instanceof Component inner)) {
363+
return Collections.emptyList();
364+
}
365+
366+
TranslatableContents innerTc = TooltipMatcher.translatable(inner);
367+
if (innerTc != null && innerTc.getArgs().length > 0) {
368+
List<Category> out = new ArrayList<>();
369+
for (Object arg : innerTc.getArgs()) {
370+
if (arg instanceof Component cat) {
371+
out.add(new Category(cat.getString(), categoryId(cat), cat));
372+
} else {
373+
String name = String.valueOf(arg);
374+
out.add(new Category(name, null, Component.literal(name)));
375+
}
359376
}
360-
names.addAll(splitCategories(inner));
377+
return out;
361378
}
362-
return names;
379+
380+
List<Category> out = new ArrayList<>();
381+
for (String name : splitCategories(inner.getString())) {
382+
out.add(new Category(name, null, Component.literal(name)));
383+
}
384+
return out;
385+
}
386+
387+
private static List<Category> extractCategoriesRange(List<Component> tooltip, int from, int toExclusive) {
388+
List<Category> out = new ArrayList<>();
389+
for (int k = from; k < toExclusive; k++) {
390+
out.addAll(extractCategories(tooltip.get(k)));
391+
}
392+
return out;
393+
}
394+
395+
// Returns the Apoth category id from a category name component's key (text.apotheosis.category.<id>.plural),
396+
// so config values like "chestplate" match regardless of the rendered "Chestplates" text or locale.
397+
private static String categoryId(Component cat) {
398+
TranslatableContents tc = TooltipMatcher.translatable(cat);
399+
if (tc == null) {
400+
return null;
401+
}
402+
String key = tc.getKey();
403+
int at = key.lastIndexOf("category.");
404+
if (at < 0) {
405+
return null;
406+
}
407+
String id = key.substring(at + "category.".length());
408+
if (id.endsWith(".plural")) {
409+
id = id.substring(0, id.length() - ".plural".length());
410+
}
411+
return id;
363412
}
364413

365414
// Splits "Swords, Bows, ..." into trimmed, non empty names.
@@ -374,27 +423,46 @@ private static List<String> splitCategories(String inner) {
374423
return names;
375424
}
376425

377-
// Drops any names listed in hidden_gem_categories, case insensitive.
378-
private static List<String> filterHidden(List<String> categories) {
379-
List<? extends String> hidden = Config.HIDDEN_GEM_CATEGORIES.get();
380-
if (hidden == null || hidden.isEmpty()) {
426+
// Keeps the categories the user has not hidden, matching the Apoth id from the translation key (so
427+
// config can use ids like "chestplate") and the rendered name (so "Chestplates" works too).
428+
private static List<Category> filterHidden(List<Category> categories) {
429+
Set<String> hidden = hiddenSet();
430+
if (hidden.isEmpty()) {
381431
return categories;
382432
}
383-
Set<String> hiddenSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
384-
hiddenSet.addAll(hidden);
385-
List<String> filtered = new ArrayList<>(categories.size());
386-
for (String name : categories) {
387-
if (!hiddenSet.contains(name)) {
388-
filtered.add(name);
433+
List<Category> kept = new ArrayList<>(categories.size());
434+
for (Category cat : categories) {
435+
boolean hide = (cat.id() != null && hidden.contains(cat.id())) || hidden.contains(cat.name());
436+
if (!hide) {
437+
kept.add(cat);
389438
}
390439
}
391-
return filtered;
440+
return kept;
392441
}
393442

394-
// Rebuilds a Fits In category bullet with the teal styling after dropping hidden categories, used
395-
// by both compact and full mode.
396-
private static Component categoryBullet(String text) {
397-
return Component.translatable("text.apotheosis.dot_prefix", Component.literal(text))
443+
private static List<String> namesOf(List<Category> categories) {
444+
List<String> names = new ArrayList<>(categories.size());
445+
for (Category cat : categories) {
446+
names.add(cat.name());
447+
}
448+
return names;
449+
}
450+
451+
// Rebuilds a Fits In category bullet from the kept categories after dropping hidden ones. Apoth
452+
// joins the categories through a "%s, %s" translatable, so reconstruct that with one %s per kept
453+
// category and the original category components as args, keeping them translatable.
454+
private static Component rebuildCategoryBullet(List<Category> kept) {
455+
StringBuilder fmt = new StringBuilder();
456+
Object[] args = new Object[kept.size()];
457+
for (int i = 0; i < kept.size(); i++) {
458+
fmt.append("%s");
459+
if (i < kept.size() - 1) {
460+
fmt.append(", ");
461+
}
462+
args[i] = kept.get(i).component();
463+
}
464+
Component join = Component.translatable(fmt.toString(), args);
465+
return Component.translatable("text.apotheosis.dot_prefix", join)
398466
.withStyle(Style.EMPTY.withColor(FITS_IN_COLOR));
399467
}
400468

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

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,32 @@
55
import com.nightwielder.apothictooltipcleanup.util.TooltipMatcher;
66
import net.minecraft.client.gui.screens.Screen;
77
import net.minecraft.network.chat.Component;
8+
import net.minecraft.world.item.ItemStack;
89

910
import java.util.List;
1011

11-
// Hides the affix type prefix lines (While held, On hit, On block, Passive).
12+
// Strips the Apotheosis affix prefix and suffix from the item name, leaving the base item name. Apoth
13+
// renames affixed items with a misc.apotheosis.affix_name template, so tooltip line 0 carries that key.
1214
public final class PrefixCleaner {
1315
private PrefixCleaner() {}
1416

15-
// Drops the prefix lines when the mode hides them and returns true if a hidden line is alt revealable.
16-
public static boolean apply(List<Component> tooltip) {
17+
// Replaces the affixed item name with the plain base name when the mode hides it and returns true
18+
// if a hidden name is alt revealable.
19+
public static boolean apply(ItemStack stack, List<Component> tooltip) {
1720
String mode = Config.AFFIX_PREFIXES_MODE.get();
1821
boolean altDown = Screen.hasAltDown();
1922
if (!HideMode.hides(mode, altDown)) {
2023
return false;
2124
}
22-
boolean removed = tooltip.removeIf(c -> TooltipMatcher.keyStartsWith(c, "text.apotheosis.affix_type.while_held")
23-
|| TooltipMatcher.keyStartsWith(c, "text.apotheosis.affix_type.on_hit")
24-
|| TooltipMatcher.keyStartsWith(c, "text.apotheosis.affix_type.on_block")
25-
|| TooltipMatcher.keyStartsWith(c, "text.apotheosis.affix_type.passive"));
26-
return removed && HideMode.revealable(mode, altDown);
25+
if (tooltip.isEmpty()) {
26+
return false;
27+
}
28+
Component name = tooltip.get(0);
29+
if (!TooltipMatcher.keyStartsWith(name, "misc.apotheosis.affix_name")) {
30+
return false;
31+
}
32+
Component base = stack.getItem().getName(stack);
33+
tooltip.set(0, Component.empty().append(base).withStyle(name.getStyle()));
34+
return HideMode.revealable(mode, altDown);
2735
}
2836
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public static void onTooltip(ItemTooltipEvent event) {
5050
// each handler returns true if it hid something Alt can reveal. OR them together so
5151
// AltExpandHandler knows whether to add the prompt.
5252
boolean anyHidden = false;
53-
anyHidden |= PrefixCleaner.apply(tooltip);
53+
anyHidden |= PrefixCleaner.apply(stack, tooltip);
5454
anyHidden |= SourceLineRemover.apply(tooltip);
5555
anyHidden |= SummarizationDisabler.apply(tooltip);
5656
if (ApotheosisDetector.isApothicAttributesLoaded()) {

0 commit comments

Comments
 (0)