You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Make crafted items follow their template's required class - #53
Reviewed: Fable 5.2 APPROVE at 834cf16 (4 minor; class-sync failure guard and case-insensitive match fixed in 0688629, no re-review: no saved-data change)
Second opinion: CodeRabbit APPROVE at 834cf16 (no findings)
Dev-tested: passed at 0688629 on TFMCDev01 (DEV-20261114-0010, 2026-11-14 00:24-00:26 UTC, bot ACTierBot). CUSTOM_WARHAMMER without Warden: crafted warhammer (Masterwork, Sapphire socketed, durability 463/500) has the 4-class list and a Warden is refused ("You don't have the right class!", 0 damage); a baseline relog changes nothing. Warden restored + mi reload + relog: exactly one [AC][ClassSync] WARHAMMERS.CUSTOM_WARHAMMER: [Crusader, Templar, Cleric, Juggernaut] -> [Crusader, Templar, Cleric, Juggernaut, Warden]. Full NBT diff: only MMOITEMS_REQUIRED_CLASS, MMOITEMS_DYNAMIC_LORE and the lore class line changed; gem, durability, name, stats, quality and tier lines identical. The Warden then hits for damage. A second relog: no ClassSync line, all items identical. The non-AC mi give warhammer (old list), a vanilla sword and an already-matching warhammer are untouched. No AC warnings or errors. Template restored byte-identical; bot cleaned.
Local tests: passed at 0688629 (191 tests; only the 4 known Windows-only station persistence failures, which also fail on origin/main; Linux CI runs the coverage gate)
What
AdvancedCrafting's item refresh now makes a crafted MMOItems item's required class follow its current MMOItems template.
Why
MMOItems stamps MMOITEMS_REQUIRED_CLASS on an item when it is built. AC rebuilds crafted items from the item's own NBT (LiveMMOItem), not from the template, so a later template change never reaches existing pieces. On Main, CUSTOM_WARHAMMER gained Warden on 2026-11-07, but a pre-11-07 Parsusite Warhammer still carries Crusader, Templar, Cleric, Juggernaut, so a Warden can't use it. Bumping the MMOItems revision-id isn't an option because it would wipe AC's crafted stats.
How
New utils/RequiredClassSync.sync(ItemStack), called from AcItemRefresher.refreshIfOutdated after the stat/lore refresh and before the look migration. It runs on every existing refresh trigger: join and character session (every inventory, armour, off-hand and ender chest slot), opened chests/barrels/storage entities, clicks, hotbar, armour equip and drops.
It only handles AdvancedCrafting crafts (items with the craft recipe tag) that are MMOItems items with a known template. Anything else, including an unknown or removed template, is returned unchanged.
Cheap check: it reads the NBT class string, splits it, and compares it with the template's required-class as sets (trimmed, so order, spacing and repeats don't count). If they match, it returns the same item: no LiveMMOItem, no rebuild, no write.
On a mismatch: it sets REQUIRED_CLASS to the template list in template order, or removes the stat when the template has no required-class. Then it rebuilds through mmo.newBuilder().build(), so MMOItems regenerates the class lore line. The rebuild keeps what the stat refresh keeps: wear (RefreshKeeper.keepWear); skin/model, display name and all PDC (keepAppearance); and amount. It reapplies the stored tier line. No other stat is touched.
If the item has a HSTRY_REQUIRED_CLASS stat history, only the history's original layer is compared and replaced, so gem and external layers stay.
Each change is logged as [AC][ClassSync] <TYPE>.<ID>: [old] -> [new].
The same code works for any future class change on any AC weapon or armour template.
Tests
RequiredClassSyncTest:
old list → template list with Warden added, in template order
an already-matching item is not read or rebuilt
a template without required-class removes the restriction
an unknown template, a non-crafted item, a non-MMOItems item, null and air are all left untouched
other stats and gem histories stay identical (real MMOItem and StatHistory objects)
order, spacing and repeats count as equal
a matching stat history is not rebuilt
a full refresh keeps amount, PDC, provenance and the tier line
Dev test notes
Hold or carry a warhammer crafted before 2026-11-07 as a Warden and rejoin. It should become usable, its lore should list Warden, and the log should show one [AC][ClassSync] line.
A second rejoin should log nothing.
Name, quality line, gems, stats and durability should be unchanged.
Crafted pieces keep the MMOITEMS_REQUIRED_CLASS list stamped at craft
time, and the refresh rebuilds them from their own NBT, so a class added
to a template (Warden on CUSTOM_WARHAMMER) never reached old pieces.
The item refresh (join, character session, opened storage, clicks) now
compares a crafted MMOItems item's class list with its current template
as a set (order, spacing and repeats ignored). On a mismatch it sets the
REQUIRED_CLASS stat to the template list in template order, or removes it
when the template has none, and rebuilds through MMOItems' builder so the
lore line follows; wear, look, name, PDC and the tier line are kept like
the stat refresh does. With a class stat history only its original layer
changes. Matching items, unknown templates and non-crafted items are left
untouched without a rebuild.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This repository does not receive automatic reviews because it has fewer than 10 stars.
Run configuration
Source mode: Auto
Repository: Unavailable
Branch: Unavailable
File: No configuration file from this repository applied
Commit: Unavailable
Layers: Organization UI
Review profile: CHILL
Plan: Advanced
Run ID: 780438e1-eef3-455f-b427-f5f7428315e4
No actionable comments were generated in the recent review.
Summary
Summary by CodeRabbit
Bug Fixes
Crafted items now synchronise their required classes with the current item template during refresh, including when no other refresh is needed.
Updates preserve item wear, appearance, quantity, craft tier and other existing item data.
The change adds a utility to synchronise a crafted item’s required classes with its MMOItems template. Item refresh now runs this synchronisation before armour-look migration.
The utility compares class sets without regard to order, spacing or duplicates. It updates or removes the required-class stat when needed, and tests cover item rebuilding, history and metadata preservation, and unchanged inputs.
Apply synchronisation during refresh src/main/java/net/tfminecraft/advancedcrafting/utils/AcItemRefresher.java
Item refresh passes the selected item through required-class synchronisation before armour-look migration.
Crafted items now pick up their template's required class on refresh, and matching or unsupported items are left alone. No concrete defect was established. One narrow case is unconfirmed: a template with no classes on an item that also carries gem-contributed class history. Merge risk is minimal.
- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
…s ignoring case
Review follow-ups: a class sync error no longer throws away the stat refresh done before it (it is logged
and the item kept), and a case-only template change (warden -> Warden) is no change, as MMOItems matches
class names ignoring case. The update() javadoc now says a template without classes drops the whole stat.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
size:L100-499 effective changed lines (tests excluded in mixed PRs).
1 participant
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status record
mi reload+ relog: exactly one[AC][ClassSync] WARHAMMERS.CUSTOM_WARHAMMER: [Crusader, Templar, Cleric, Juggernaut] -> [Crusader, Templar, Cleric, Juggernaut, Warden]. Full NBT diff: onlyMMOITEMS_REQUIRED_CLASS,MMOITEMS_DYNAMIC_LOREand the lore class line changed; gem, durability, name, stats, quality and tier lines identical. The Warden then hits for damage. A second relog: no ClassSync line, all items identical. The non-ACmi givewarhammer (old list), a vanilla sword and an already-matching warhammer are untouched. No AC warnings or errors. Template restored byte-identical; bot cleaned.What
AdvancedCrafting's item refresh now makes a crafted MMOItems item's required class follow its current MMOItems template.
Why
MMOItems stamps
MMOITEMS_REQUIRED_CLASSon an item when it is built. AC rebuilds crafted items from the item's own NBT (LiveMMOItem), not from the template, so a later template change never reaches existing pieces. On Main,CUSTOM_WARHAMMERgained Warden on 2026-11-07, but a pre-11-07 Parsusite Warhammer still carriesCrusader, Templar, Cleric, Juggernaut, so a Warden can't use it. Bumping the MMOItems revision-id isn't an option because it would wipe AC's crafted stats.How
utils/RequiredClassSync.sync(ItemStack), called fromAcItemRefresher.refreshIfOutdatedafter the stat/lore refresh and before the look migration. It runs on every existing refresh trigger: join and character session (every inventory, armour, off-hand and ender chest slot), opened chests/barrels/storage entities, clicks, hotbar, armour equip and drops.required-classas sets (trimmed, so order, spacing and repeats don't count). If they match, it returns the same item: noLiveMMOItem, no rebuild, no write.REQUIRED_CLASSto the template list in template order, or removes the stat when the template has norequired-class. Then it rebuilds throughmmo.newBuilder().build(), so MMOItems regenerates the class lore line. The rebuild keeps what the stat refresh keeps: wear (RefreshKeeper.keepWear); skin/model, display name and all PDC (keepAppearance); and amount. It reapplies the stored tier line. No other stat is touched.HSTRY_REQUIRED_CLASSstat history, only the history's original layer is compared and replaced, so gem and external layers stay.[AC][ClassSync] <TYPE>.<ID>: [old] -> [new].Tests
RequiredClassSyncTest:required-classremoves the restrictionMMOItemandStatHistoryobjects)Dev test notes
[AC][ClassSync]line.🤖 Generated with Claude Code